版博士V2.0程序
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

9701 lignes
529 KiB

  1. using BarTenderPrint;
  2. using CCWin.SkinClass;
  3. using CCWin.SkinControl;
  4. using CCWin.Win32;
  5. using CCWin.Win32.Com;
  6. using CCWin.Win32.Const;
  7. using HalconDotNet;
  8. using HZH_Controls;
  9. using HZH_Controls.Forms;
  10. using ImageToolKits;
  11. using MaiMuAOI.ImageProcessing;
  12. using MaiMuAOI.SysUI.ProcessStep.Prop;
  13. using MaiMuAOI.SysUI.ProductAndStep;
  14. using MaiMuControl.Device;
  15. using MaiMuControl.Device.AxisDev;
  16. using MaiMuControl.Device.AxisDev.Advantech;
  17. using MaiMuControl.Device.AxisDev.PMS;
  18. using MaiMuControl.Device.CamDev;
  19. using MaiMuControl.Device.IOCardDev;
  20. using MaiMuControl.Device.IOCardDev.Advantech;
  21. using MaiMuControl.Device.LightDev;
  22. using MaiMuControl.Device.LightDev.CST;
  23. using MaiMuControl.Device.LightDev.Rsee;
  24. using MaiMuControl.Device.SenSorDev;
  25. using MaiMuControl.Device.SenSorDev.HeightSensor;
  26. using MaiMuControl.Device.SenSorDev.TensionSensor;
  27. using MaiMuControl.SysStatusMgr.CloudMgr;
  28. using MaiMuControl.SysStatusMgr.MqttMgr;
  29. using MaiMuControl.SysStatusMgr.StatusMgr;
  30. using MaiMuControl.SysStatusMgr.UserMgr;
  31. using MaiMuControl.Utils;
  32. using Models;
  33. using Newtonsoft.Json;
  34. using Newtonsoft.Json.Linq;
  35. using OpenCvSharp;
  36. using OpenCvSharp.Flann;
  37. using ProductionControl;
  38. using ProductionControl.UI;
  39. using ProductionControl.UIExtend;
  40. using Service;
  41. using SqlSugar;
  42. using System;
  43. using System.Collections;
  44. using System.Collections.Generic;
  45. using System.Data;
  46. using System.Diagnostics;
  47. using System.Drawing;
  48. using System.Drawing.Imaging;
  49. using System.IO;
  50. using System.Linq;
  51. using System.Reflection;
  52. using System.Runtime.Remoting.Lifetime;
  53. using System.Security.Cryptography;
  54. using System.Text;
  55. using System.Threading;
  56. using System.Threading.Tasks;
  57. using System.Web;
  58. using System.Windows.Forms;
  59. using System.Xml.Linq;
  60. using ToolKits.Disk;
  61. using ToolKits.EnumTool;
  62. using ToolKits.Http;
  63. using ToolKits.mAPI;
  64. using Yolo5;
  65. using static MaiMuAOI.ImageProcessing.DefectLib;
  66. using static MaiMuAOI.ImageProcessing.SizeLib;
  67. using static MaiMuAOI.SysCtrl.SysMgr;
  68. using static MaiMuControl.SysStatusMgr.MqttMgr.MyMqttClient;
  69. using static System.Net.Mime.MediaTypeNames;
  70. using static System.Windows.Forms.VisualStyles.VisualStyleElement;
  71. namespace MaiMuAOI.SysCtrl
  72. {
  73. /// <summary>
  74. /// 主系统控制
  75. /// </summary>
  76. public class SysMgr
  77. {
  78. #region singleton实例化
  79. private static SysMgr _instance;
  80. private static readonly object _lock = new object();
  81. public static SysMgr Instance
  82. {
  83. get
  84. {
  85. if (_instance == null)
  86. {
  87. lock (_lock)
  88. {
  89. if (_instance == null)
  90. {
  91. _instance = new SysMgr();
  92. }
  93. }
  94. }
  95. return _instance;
  96. }
  97. }
  98. #endregion
  99. public CameraEnumType SysUseCamFront = CameraEnumType.MVSCamera_CC;
  100. public CameraEnumType SysUseCamBack = CameraEnumType.MVSCamera_GENTL;
  101. public LightDevNameEnum SysUseLight = LightDevNameEnum.CST;
  102. //主流程
  103. private Thread _mainThread;
  104. private CancellationTokenSource _cts;
  105. /// <summary>
  106. /// 流程序号
  107. /// </summary>
  108. private int CurrProcessIndex = 0;
  109. /// <summary>
  110. /// 当前点位号
  111. /// </summary>
  112. private int CurrPoinntCount = 0;
  113. /// <summary>
  114. /// 总计时
  115. /// </summary>
  116. private Stopwatch stopWatch;
  117. //运动曲线 默认T型 0更快
  118. public int MotionST = 0;
  119. public double DefaultSpeed = 200;
  120. //系统状态
  121. private StatusMgr statusMgr;
  122. public StatusMgr StatusMgr { get { return statusMgr; } }
  123. //用户管理
  124. private UserMgr userMgr;
  125. public UserMgr UserMgr { get { return userMgr; } }
  126. //系统配置管理
  127. private ConfMgr confMgr;
  128. //web服务器
  129. private WebService webService;
  130. //局域网云端
  131. private bool init_Cloud;
  132. private CloudMgr cloudMgr;
  133. private int DailyOutput;
  134. //产品数据服务器
  135. private MyMqttHostServer myMqttHostServer;
  136. private MyMqttClient myMqttClient;
  137. //产品列表
  138. private List<string> productCodeList = new List<string>();
  139. public List<string> ProductCodeList { get { return productCodeList; } }
  140. //产品ID列表
  141. private List<int> productIdList = new List<int>();
  142. public List<int> ProductIdList { get { return productIdList; } }
  143. //近期SN列表
  144. private List<string> productSNList = new List<string>();
  145. public List<string> ProductSNList { get { return productSNList; } }
  146. Service.ProductService PdtService;
  147. Service.OrderService OrderService;
  148. Service.ClassesService svcClasses;
  149. //可用步骤
  150. public static Dictionary<string, string> dicDevType = new Dictionary<string, string>();
  151. //2023-12-20 新流程步骤
  152. public static Dictionary<string, string> ProcessType = new Dictionary<string, string>();
  153. //图像处理
  154. private DefectLib defectLib;
  155. public DefectLib DefectLib { get { return defectLib; } }
  156. private SizeLib sizeLib;
  157. public SizeLib SizeLib { get { return sizeLib; } }
  158. private int SizeNGCnt;
  159. //流程处理
  160. private ForLib forLib;
  161. private IFLib ifLib;
  162. /// <summary>
  163. /// 当前产品
  164. /// </summary>
  165. private Models.Product CurrProductModel = null;
  166. /// <summary>
  167. /// 当前料号
  168. /// </summary>
  169. private Order order = new Order();
  170. //产品-厚度base校正点位索引
  171. private int ProductPT_HeightBaseNum = 0;
  172. //线宽,张力,厚度,PT
  173. private List<double> lstTension = new List<double>();
  174. private List<double> lstHeight = new List<double>();
  175. private List<double> lstHeightBase = new List<double>();
  176. private List<double> lstLineWidth = new List<double>();
  177. private List<double> lstPT = new List<double>();
  178. private List<double> lstTestData = new List<double>();
  179. //系统判断是否是新流程
  180. private bool IsNewStepProcessVel;
  181. //当前测试结果
  182. private int CurrStepResult = 0;
  183. //当前厚度基准是否完成
  184. private bool IsCurrHeightBase = false;
  185. //双控按钮信号
  186. private bool IsGetStartSig = false;
  187. //自动聚焦参数
  188. private bool IsAutoFocus { get; set; }
  189. private double FocusStep { get; set; }
  190. private double DirStep { get; set; }
  191. private int DirWaitTime { get; set; }
  192. private int FocusTimeOut { get; set; }
  193. //缺陷循环参数
  194. private double Left_X = 0;
  195. private double Left_Y = 0;
  196. private int X_For = 0;
  197. private int Y_For = 0;
  198. private int X_For_Index = 0;
  199. private int Y_For_Index = 0;
  200. //图纸选点参数
  201. private int[] CurrAdaqter = new int[9];
  202. //image.save保存锁,防止多线程报错
  203. private object ImageSaveObj = new object();
  204. //2024-03-12 加入打印列表
  205. private List<PrintInfo> CurrPrintInfos = new List<PrintInfo>();
  206. //2024-03-26 加入整体工单打印列表
  207. private List<PrintInfo> CurrOrderPrintInfos = new List<PrintInfo>();
  208. //2024-03-26 加入尺寸和缺陷禁用快捷键
  209. private bool SizeEnable;
  210. private bool DefectEnable;
  211. //2024-03-26 加入单号检测总数,ok数,ng数
  212. private int TotalCnt = 0;
  213. private int CurrDefectIndex = 0;
  214. private List<Order> CurrDefectOrders = new List<Order>();
  215. #region 图像显示列表
  216. private class scannerGBmpLoc
  217. {
  218. public scannerGBmpLoc(Mat mat, double xmm, double ymm)
  219. {
  220. bmp = mat;
  221. Xmm = xmm;
  222. Ymm = ymm;
  223. }
  224. public Mat bmp { get; private set; }
  225. public double Xmm { get; private set; }
  226. public double Ymm { get; private set; }
  227. }
  228. private class scannerCBmpLoc
  229. {
  230. public scannerCBmpLoc(string path, double posX, double posY)
  231. {
  232. Path = path;
  233. PosX = posX;
  234. PosY = posY;
  235. }
  236. public scannerCBmpLoc(HObject himg, double posX, double posY)
  237. {
  238. Himage = himg;
  239. PosX = posX;
  240. PosY = posY;
  241. }
  242. public HObject Himage { get; private set; }
  243. public string Path { get; private set; }
  244. public double PosX { get; private set; }
  245. public double PosY { get; private set; }
  246. }
  247. private Queue<scannerGBmpLoc> scannerGBmpQueue = new Queue<scannerGBmpLoc>();
  248. private Queue<scannerCBmpLoc> scannerCBmpQueue = new Queue<scannerCBmpLoc>();
  249. /// <summary>
  250. /// 比对失败的图片
  251. /// </summary>
  252. public List<Bitmap> lstCompareFailZoomImage = new List<Bitmap>();
  253. /// <summary>
  254. /// --333输出变量供后面多个777使用
  255. /// </summary>
  256. public HObject contoursAffineTrans1_Out;
  257. /// <summary>
  258. /// 对比引索
  259. /// </summary>
  260. private int compBmpIndex = 0;//比对777图的索引
  261. /// <summary>
  262. /// 对比张数
  263. /// </summary>
  264. private int compBmpNum = 0;//比对张数
  265. /// <summary>
  266. /// 缺陷处理图片张数
  267. /// </summary>
  268. private int defectBmpNum = 0;
  269. /// <summary>
  270. /// 缺陷处理结果
  271. /// </summary>
  272. private int defectBmpNumResult = 0;
  273. /// <summary>
  274. /// 缺陷总不良数
  275. /// </summary>
  276. private int AllDefectCount = 0;
  277. #endregion
  278. private SysMgr()
  279. {
  280. _isInit = false;
  281. _isRuning = false;
  282. statusMgr = StatusMgr.Instance;
  283. confMgr = ConfMgr.Instance;
  284. //设置本机为主机数据库
  285. statusMgr.SetMySqlIPaddr("127.0.0.1");
  286. userMgr = new UserMgr(statusMgr.MySqlIP);
  287. Service.InitDB.ConnectionString = confMgr.DBConStr;
  288. PdtService = new Service.ProductService();
  289. OrderService = new OrderService();
  290. webService = new WebService();
  291. svcClasses = new Service.ClassesService();
  292. init_Cloud = false;
  293. cloudMgr = new CloudMgr();
  294. DailyOutput = 0;
  295. myMqttHostServer = new MyMqttHostServer();
  296. myMqttClient = new MyMqttClient();
  297. scannerGBmpQueue = new Queue<scannerGBmpLoc>();
  298. scannerCBmpQueue = new Queue<scannerCBmpLoc>();
  299. lstCompareFailZoomImage = new List<Bitmap>();
  300. MotionST = 0;
  301. DefaultSpeed = 200;
  302. _cts = new CancellationTokenSource();
  303. SizeEnable = true;
  304. DefectEnable = true;
  305. IsNewStepProcessVel = false;
  306. InitDevDic();
  307. }
  308. #region 日志报警
  309. /// <summary>
  310. /// 初始化记录报警和显示
  311. /// </summary>
  312. /// <param name="tag">标头</param>
  313. /// <param name="msg">内容</param>
  314. /// <param name="warning">报警状态</param>
  315. private void InitLog(string msg, string tag = "初始化", WarningEnum warning = WarningEnum.Normal)
  316. {
  317. OnInitRuning(new InitEventArgs(msg));
  318. statusMgr.GotoWarning(warning, tag, msg);
  319. }
  320. /// <summary>
  321. /// 记录报警和显示
  322. /// </summary>
  323. /// <param name="tag">标头</param>
  324. /// <param name="msg">内容</param>
  325. /// <param name="warning">报警状态</param>
  326. private void Log(string tag, string msg, WarningEnum warning = WarningEnum.Normal)
  327. {
  328. OnMainRuning(new MainEventArgs(tag, msg, warning));
  329. statusMgr.GotoWarning(warning, tag, msg);
  330. //开启云端
  331. if((init_Cloud)&&(warning != WarningEnum.Normal))
  332. {
  333. //上传报警状态和信息
  334. string statusStr = warning == WarningEnum.Normal ? "正常" : warning == WarningEnum.Low ? "警告":"系统报警" ;
  335. cloudMgr.SendTopic("device/attributes", $"{{\"status\": \"{statusStr}\", \"alm\": \"{tag}-{msg}\", " +
  336. $"\"name\": \"{confMgr.SysConfigParams.CloudThisName}\", \"DailyOutput\": \"{DailyOutput}\"}}");
  337. }
  338. }
  339. #endregion
  340. #region 本地云上传
  341. /// <summary>
  342. /// 上传当日产量
  343. /// </summary>
  344. private void SendDailyOutput()
  345. {
  346. //开启云端
  347. if (init_Cloud)
  348. {
  349. try
  350. {
  351. if(!cloudMgr.SendTopic("device/attributes", $"{{ \"DailyOutput\": \"{DailyOutput}\"}}"))
  352. Log("云端", $"上传失败", WarningEnum.Low);
  353. }
  354. catch (Exception e)
  355. {
  356. Log("云端", $"上传失败:{e.Message}", WarningEnum.Low);
  357. }
  358. }
  359. }
  360. /// <summary>
  361. /// 上传正常状态
  362. /// </summary>
  363. public void SendStatus()
  364. {
  365. //开启云端
  366. if (init_Cloud)
  367. {
  368. //上传报警状态和信息
  369. string statusStr = "正常";
  370. switch(StatusMgr.Status)
  371. {
  372. case SystemStsEnum.Manual:
  373. statusStr = "人工操作";
  374. break;
  375. case SystemStsEnum.Standby:
  376. statusStr = "正常待机";
  377. break;
  378. case SystemStsEnum.Initial:
  379. statusStr = "初始化";
  380. break;
  381. case SystemStsEnum.Auto:
  382. statusStr = "自动运行";
  383. break;
  384. case SystemStsEnum.Pause:
  385. statusStr = "自动暂停";
  386. break;
  387. case SystemStsEnum.SetParams:
  388. statusStr = "参数设置";
  389. break;
  390. case SystemStsEnum.Debug:
  391. statusStr = "调试";
  392. break;
  393. case SystemStsEnum.Warning:
  394. statusStr = "系统报警";
  395. break;
  396. case SystemStsEnum.Bootload:
  397. statusStr = "Bootload";
  398. break;
  399. default:
  400. statusStr = "未知";
  401. break;
  402. }
  403. try
  404. {
  405. if(!cloudMgr.SendTopic("device/attributes", $"{{\"status\": \"{statusStr}\", \"alm\": \"无报警信息\", " +
  406. $"\"name\": \"{confMgr.SysConfigParams.CloudThisName}\", \"DailyOutput\": \"{DailyOutput}\"}}"))
  407. Log("云端", $"上传失败", WarningEnum.Low);
  408. }
  409. catch (Exception e)
  410. {
  411. Log("云端", $"上传失败:{e.Message}", WarningEnum.Low);
  412. }
  413. }
  414. }
  415. #endregion
  416. #region 产品服务器
  417. public bool InitPdtService()
  418. {
  419. if (confMgr.SysConfigParams.OpenPdtServer)
  420. {
  421. try
  422. {
  423. if (confMgr.SysConfigParams.IsPdtServer)
  424. {
  425. myMqttHostServer.StartAsync(confMgr.SysConfigParams.PdtServerPort);
  426. Log("产品服务", "产品服务器打开");
  427. //自发自测
  428. //myMqttClient.MqttClientStart(confMgr.SysConfigParams.PdtServerIP, confMgr.SysConfigParams.PdtServerPort,
  429. // "admin", "123456", confMgr.SysConfigParams.CloudThisName, "pdtinfo");
  430. //myMqttClient.RecvRuning += Recv_Process;
  431. //Log("产品服务", "产品客户端打开");
  432. }
  433. else
  434. {
  435. myMqttClient.MqttClientStart(confMgr.SysConfigParams.PdtServerIP, confMgr.SysConfigParams.PdtServerPort,
  436. "admin", "123456", confMgr.SysConfigParams.CloudThisName, "pdtinfo");
  437. myMqttClient.RecvRuning += Recv_Process;
  438. Log("产品服务", "产品客户端打开");
  439. }
  440. return true;
  441. }
  442. catch (Exception e)
  443. {
  444. Log("产品服务", "产品服务器或客户端打开失败!", WarningEnum.Low);
  445. return false;
  446. }
  447. }
  448. return true;
  449. }
  450. //产品数据解析
  451. private int pdtID = -1;
  452. private List<byte[]> FileDataList = new List<byte[]>();//文件数据
  453. private byte[] Combine(params byte[][] arrays)
  454. {
  455. byte[] rv = new byte[arrays.Sum(a => a.Length)];
  456. int offset = 0;
  457. foreach (byte[] array in arrays)
  458. {
  459. System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
  460. offset += array.Length;
  461. }
  462. return rv;
  463. }
  464. private void Recv_Process(object sender, RecvEventArgs e)
  465. {
  466. Thread t = new Thread(() =>
  467. {
  468. if (e.Topic == "TopicToServer")
  469. {
  470. if (pdtID >= 0)
  471. {
  472. Log("产品服务", "开始接收产品文件");
  473. //接收文件
  474. JObject json = JObject.Parse(e.Payload);
  475. string filename = json.Value<string>("FileName");
  476. byte[] datas = Convert.FromBase64String(json.Value<string>("data"));
  477. int index = int.Parse(json.Value<string>("index"));
  478. int packageNums = int.Parse(json.Value<string>("packageNums"));
  479. if (index == 0)
  480. FileDataList.Clear();
  481. FileDataList.Add(datas);
  482. if (index == (packageNums - 1))
  483. {
  484. byte[] alldatas = Combine(FileDataList.ToArray());
  485. //创建文件夹
  486. if (!Directory.Exists(ConfMgr.Instance.ProjectDir + $"\\{pdtID}\\"))
  487. {
  488. Directory.CreateDirectory(ConfMgr.Instance.ProjectDir + $"\\{pdtID}\\");
  489. }
  490. //2、将byte[]数组保存成文件
  491. File.WriteAllBytes(ConfMgr.Instance.ProjectDir + $"\\{pdtID}\\" + filename, alldatas);
  492. Log("产品服务", $"保存文件:{ConfMgr.Instance.ProjectDir + $"\\{pdtID}\\" + filename}");
  493. }
  494. }
  495. //else
  496. // Log("产品服务", "中断接收产品文件", WarningEnum.Low);
  497. }
  498. else if (e.Topic == "pdtinfo")
  499. {
  500. Log("产品服务", "开始接收产品数据");
  501. pdtID = -1;
  502. //解析产品数据
  503. Product pdt = JsonConvert.DeserializeObject<Product>(e.Payload);
  504. pdt.Id = 0;
  505. pdt.CompleteCount = 0;
  506. pdt.CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code;
  507. Models.Attachment attachmentFile = pdt.AttachmentList.FirstOrDefault(m => m.Type == 0);
  508. string fileName = attachmentFile.Name;
  509. string fileExtend = attachmentFile.ExtendName;
  510. string fileOnlyName = fileName.Substring(0, fileName.Length - fileExtend.Length);
  511. //判断是否有同样名称数据
  512. Product Havepdt = PdtService.GetModelNav(pdt.Code);
  513. if(Havepdt != null)
  514. {
  515. Log("产品服务", $"已存在料号:{pdt.Code}!", WarningEnum.Low);
  516. return;
  517. }
  518. try
  519. {
  520. bool result = PdtService.InsertNav(pdt);
  521. }
  522. catch (Exception ex)
  523. {
  524. //MyMqttService._recvGet = true;
  525. Log("产品服务", $"保存错误:{ex.Message}", WarningEnum.Low);
  526. return;
  527. }
  528. pdt = PdtService.GetModelNav(pdt.Code);
  529. attachmentFile = pdt.AttachmentList.FirstOrDefault(m => m.Type == 0);
  530. pdtID = pdt.Id;//获取新id
  531. if (attachmentFile != null)
  532. {
  533. attachmentFile.Type = 0;//图纸
  534. attachmentFile.NameTimestamp = $"{pdt.Id}\\{fileOnlyName}";
  535. attachmentFile.Name = fileName;
  536. attachmentFile.ExtendName = fileExtend;
  537. }
  538. else
  539. {
  540. pdt.AttachmentList.Add(new Models.Attachment()
  541. {
  542. TBName = "product",
  543. Type = 0,
  544. NameTimestamp = $"{pdt.Id}\\{fileOnlyName}",
  545. Name = fileName,
  546. ExtendName = fileExtend,
  547. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  548. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  549. });
  550. }
  551. if (!PdtService.UpdateNav(pdt))
  552. throw new Exception("保存文件失败!");
  553. //MyMqttService._recvGet = true;
  554. }
  555. Log("产品服务", "接收完成");
  556. });
  557. t.Start();
  558. }
  559. /// <summary>
  560. /// 发送产品数据
  561. /// </summary>
  562. /// <param name="model"></param>
  563. /// <returns></returns>
  564. public bool SendPdtData(Product model)
  565. {
  566. if(model == null)
  567. {
  568. MessageBox.Show("无产品数据!","错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  569. return false;
  570. }
  571. Models.Attachment attachmentFile = model.AttachmentList.FirstOrDefault(m => m.Type == 0);
  572. DialogResult dr = DialogResult.Cancel;
  573. if ((attachmentFile == null)|| (model.MapPath == null) || (string.IsNullOrEmpty(model.MapPath)))
  574. {
  575. dr = MessageBox.Show("无产品图纸数据,是否继续?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
  576. if (dr == DialogResult.Cancel)
  577. {
  578. return false;
  579. }
  580. }
  581. string sjson = JsonConvert.SerializeObject(model);
  582. bool rt = MyMqttService.PublishData("pdtinfo", sjson);
  583. if (!rt)
  584. {
  585. MessageBox.Show("发送失败,网络错误!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  586. return false;
  587. }
  588. //无法做到发送之后等待返回结果,因为多机台客户端无法同步返回
  589. //DateTime dt = DateTime.Now;
  590. //while (!MyMqttService._recvGet)
  591. //{
  592. // Thread.Sleep(5);
  593. // if ((DateTime.Now - dt).TotalSeconds > 10)
  594. // {
  595. // MessageBox.Show("发送接收失败,网络错误!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  596. // return false;
  597. // }
  598. //}
  599. Thread.Sleep(2000); //发送数据之后,等待2s发送文件
  600. if(dr == DialogResult.Cancel)
  601. {
  602. rt = MyMqttService.PublishFiles(ConfMgr.Instance.ProjectDir + $"\\{model.Id}\\");
  603. }
  604. if(!rt)
  605. {
  606. return false;
  607. }
  608. return true;
  609. }
  610. #endregion
  611. #region 硬件
  612. #region 硬件字段
  613. private AxisDev axisDev;
  614. /// <summary>
  615. /// 运动板卡
  616. /// </summary>
  617. public AxisDev AxisDev { get { return axisDev; } }
  618. private BoardCfgParams boardCfgParams;
  619. private HomeVelocityParams homeParamsX1;
  620. public HomeVelocityParams HomeParamsX1 { get { return homeParamsX1; } }
  621. private HomeVelocityParams homeParamsX2;
  622. public HomeVelocityParams HomeParamsX2 { get { return homeParamsX2; } }
  623. private HomeVelocityParams homeParamsY;
  624. public HomeVelocityParams HomeParamsY { get { return homeParamsY; } }
  625. private HomeVelocityParams homeParamsZ;
  626. public HomeVelocityParams HomeParamsZ { get { return homeParamsZ; } }
  627. private IOCardDev ioCardDev;
  628. /// <summary>
  629. /// io控制卡
  630. /// </summary>
  631. public IOCardDev IOCardDev { get { return ioCardDev; } }
  632. private LightDev lightDev;
  633. /// <summary>
  634. /// 光源控制
  635. /// </summary>
  636. public LightDev LightDev { get { return lightDev; } }
  637. public string LightName { get { return "Light"; } }
  638. public int LightChCount = 4;//美尚4通道,其他6通道
  639. private int snapCnt = 3;//拍照失败后重新拍照
  640. private CamDev camDevFront;
  641. /// <summary>
  642. /// 前部相机控制
  643. /// </summary>
  644. public CamDev CamDevFront { get { return camDevFront; } }
  645. private CamDev camDevBack;
  646. /// <summary>
  647. /// 后部相机控制
  648. /// </summary>
  649. public CamDev CamDevBack { get { return camDevBack; } }
  650. private ValueSensorDev tensionDev;
  651. /// <summary>
  652. /// 张力传感器
  653. /// </summary>
  654. public ValueSensorDev TensionDev { get { return tensionDev; } }
  655. private ValueSensorDev thicknessDev;
  656. /// <summary>
  657. /// 厚度传感器
  658. /// </summary>
  659. public ValueSensorDev ThicknessDev { get { return thicknessDev; } }
  660. private AxisDev lensMotorDev;
  661. /// <summary>
  662. /// 镜头电机
  663. /// </summary>
  664. public AxisDev LensMotorDev { get { return lensMotorDev; } }
  665. private PrintControl printControl;
  666. /// <summary>
  667. /// 打印机模块
  668. /// </summary>
  669. public PrintControl PrintControl { get { return printControl; } }
  670. #endregion
  671. #region 初始化和基本电机IO操作
  672. private void InitDev()
  673. {
  674. axisDev = new AdvantechMotion();
  675. ioCardDev = new AdvantechIO();
  676. if(SysUseLight == LightDevNameEnum.CST)
  677. lightDev = new CSTLight(LightName, LightChCount);
  678. else
  679. lightDev = new RseeLight(SysUseLight, LightName);
  680. tensionDev = new TensionSensor();
  681. lensMotorDev = new PmsMotion();
  682. thicknessDev = new HeightSensorDev();
  683. camDevFront = new CamDev(SysUseCamFront, confMgr.SysConfigParams.FrontCamName, confMgr.SysConfigParams.FrontCamCfgPath);
  684. camDevBack = new CamDev(SysUseCamBack, confMgr.SysConfigParams.BackCamName, confMgr.SysConfigParams.BackCamCfgPath);
  685. defectLib = new DefectLib();
  686. sizeLib = new SizeLib();
  687. forLib = new ForLib();
  688. ifLib = new IFLib();
  689. boardCfgParams= new BoardCfgParams();
  690. boardCfgParams.DevEmgLogic = 1;
  691. }
  692. /// <summary>
  693. /// 初始化硬件
  694. /// </summary>
  695. /// <returns></returns>
  696. private bool InitAllDev()
  697. {
  698. bool ret = false;
  699. InitDev();
  700. //打印机模块初始化
  701. InitLog("打印机模块初始化...");
  702. try
  703. {
  704. printControl = new PrintControl();
  705. InitLog("初始化打印机模块成功!");
  706. }
  707. catch (Exception ex)
  708. {
  709. printControl = null;
  710. InitLog($"初始化打印机模块失败! {ex.Message}");
  711. }
  712. //IO初始化
  713. InitLog("IO板卡初始化...");
  714. if (ioCardDev.InitBoard(MaiMuControl.Device.IOBordType.Advantech) < 0)
  715. {
  716. InitLog("IO板卡初始化失败!", "初始化", WarningEnum.High);
  717. return ret;
  718. }
  719. if(ioCardDev.OpenBoard(confMgr.SysConfigParams.IODevName, confMgr.SysConfigParams.IOCfgPath)<0)
  720. {
  721. InitLog("打开IO板卡失败!", "初始化", WarningEnum.High);
  722. return ret;
  723. }
  724. if (ioCardDev.ResetAllDO()<0)
  725. {
  726. InitLog("IO Reset失败!", "初始化", WarningEnum.High);
  727. return ret;
  728. }
  729. InitLog("初始化IO板卡成功!");
  730. //电机初始化
  731. InitLog("运动控制板卡初始化...");
  732. if(axisDev.InitBoard()<0)
  733. {
  734. InitLog("运动控制板卡初始化失败!", "初始化", WarningEnum.High);
  735. return ret;
  736. }
  737. if (axisDev.OpenBoard(0, confMgr.SysConfigParams.MotionCfgPath) < 0)
  738. {
  739. InitLog("打开运动控制板卡失败!", "初始化", WarningEnum.High);
  740. return ret;
  741. }
  742. //if (axisDev.LoadCfgFile(0, confMgr.SysConfigParams.MotionCfgPath) < 0)
  743. //{
  744. // InitLog("载入运动控制板卡参数失败2!", "初始化", WarningEnum.High);
  745. // return ret;
  746. //}
  747. if (axisDev.LoadBoardParams(0, boardCfgParams) < 0)
  748. {
  749. InitLog("载入运动控制板卡参数失败1!", "初始化", WarningEnum.High);
  750. return ret;
  751. }
  752. //光源初始化
  753. InitLog("光源控制器初始化...");
  754. int com_num = int.Parse(confMgr.SysConfigParams.LightCom.Remove(0, 3));
  755. if (lightDev.InitDev(com_num, confMgr.SysConfigParams.LightComBaud) < 0)
  756. {
  757. InitLog("光源控制器初始化失败!", "初始化", WarningEnum.High);
  758. return ret;
  759. }
  760. InitLog("初始化光源控制器成功!");
  761. //关闭光源
  762. for (int i = 0; i < LightChCount; i++)
  763. {
  764. lightDev.CloseLight(i + 1);
  765. }
  766. //张力传感器初始化
  767. InitLog("张力传感器初始化...");
  768. if (tensionDev.OpenDevByCom(confMgr.SysConfigParams.TensionCom, confMgr.SysConfigParams.TensionComBaud) < 0)
  769. {
  770. InitLog("张力传感器初始化失败!", "初始化", WarningEnum.High);
  771. return ret;
  772. }
  773. InitLog("初始化张力传感器成功!");
  774. //镜头电机初始化
  775. InitLog("镜头电机初始化...");
  776. lensMotorDev.InitBoard();
  777. if (lensMotorDev.OpenBoardByCom(confMgr.SysConfigParams.LensMotorCom, confMgr.SysConfigParams.LensMotorComBaud) < 0)
  778. {
  779. InitLog("镜头电机初始化失败!", "初始化", WarningEnum.High);
  780. return ret;
  781. }
  782. InitLog("初始化镜头电机成功!");
  783. //测厚传感器初始化
  784. InitLog("测厚传感器初始化...");
  785. if (thicknessDev.OpenDevByTcp(confMgr.SysConfigParams.ThicknessIP, confMgr.SysConfigParams.ThicknessPort) < 0)
  786. {
  787. InitLog("测厚传感器初始化失败!", "初始化", WarningEnum.High);
  788. return ret;
  789. }
  790. InitLog("初始化测厚传感器成功!");
  791. //前部相机初始化
  792. InitLog("前部相机初始化...");
  793. if(!camDevFront.InitCamera())
  794. {
  795. InitLog("前部相机初始化失败!", "初始化", WarningEnum.High);
  796. return ret;
  797. }
  798. if (!camDevFront.OpenCamera())
  799. {
  800. InitLog("前部相机打开失败!", "初始化", WarningEnum.High);
  801. return ret;
  802. }
  803. InitLog("初始化前部相机成功!");
  804. //后部相机初始化
  805. InitLog("后部相机初始化...");
  806. if (!camDevBack.InitCamera())
  807. {
  808. InitLog("后部相机初始化失败!", "初始化", WarningEnum.High);
  809. return ret;
  810. }
  811. if (!camDevBack.OpenCamera())
  812. {
  813. InitLog("后部相机打开失败!", "初始化", WarningEnum.High);
  814. return ret;
  815. }
  816. InitLog("初始化后部相机成功!");
  817. ret = true;
  818. return ret;
  819. }
  820. /// <summary>
  821. /// 读取硬件配置
  822. /// </summary>
  823. private bool LoadDevConfig()
  824. {
  825. homeParamsX1 = axisDev.ReadAxisCfg(confMgr.DevConfigPath, (int)AxisName.Axis0);
  826. homeParamsX2 = axisDev.ReadAxisCfg(confMgr.DevConfigPath, (int)AxisName.Axis1);
  827. homeParamsY = axisDev.ReadAxisCfg(confMgr.DevConfigPath, (int)AxisName.Axis2);
  828. homeParamsZ = axisDev.ReadAxisCfg(confMgr.DevConfigPath, (int)AxisName.Axis3);
  829. LightParams lightParams = new LightParams(LightName, LightChCount);
  830. //LightChCount = 6;
  831. //lightParams.DevName = LightName;
  832. lightParams.ComName = confMgr.SysConfigParams.LightCom;
  833. lightParams.Buad = confMgr.SysConfigParams.LightComBaud;
  834. //lightParams.ChCount = LightChCount;
  835. lightDev.WriteCfgInfo(confMgr.DevConfigPath, lightParams);
  836. DevParams devParams = new DevParams("tensionDev", confMgr.SysConfigParams.TensionCom,
  837. int.Parse(confMgr.SysConfigParams.TensionCom.Remove(0, 3)), confMgr.SysConfigParams.TensionComBaud);
  838. tensionDev.WriteDevCfg(confMgr.DevConfigPath, 0, devParams);
  839. devParams = new DevParams("thicknessDev", confMgr.SysConfigParams.ThicknessIP,
  840. confMgr.SysConfigParams.ThicknessPort);
  841. thicknessDev.WriteDevCfg(confMgr.DevConfigPath, 0, devParams);
  842. //ioCardDev.ReadCfgInfo(confMgr.DevConfigPath, "IO_1");
  843. if ((homeParamsZ == null) || (homeParamsX1 == null) || (homeParamsX2 == null) || (homeParamsY == null)||
  844. !homeParamsZ.IsValid() || !homeParamsX1.IsValid() || !homeParamsX2.IsValid() || !homeParamsY.IsValid())
  845. return false;
  846. return true;
  847. }
  848. /// <summary>
  849. /// 急停所有电机
  850. /// </summary>
  851. private void AxisAllImmediateStop()
  852. {
  853. axisDev.ImmediateStop((int)AxisName.Axis0);
  854. axisDev.ImmediateStop((int)AxisName.Axis1);
  855. axisDev.ImmediateStop((int)AxisName.Axis2);
  856. axisDev.ImmediateStop((int)AxisName.Axis3);
  857. }
  858. /// <summary>
  859. /// 减速停止
  860. /// </summary>
  861. private void AxisDStop()
  862. {
  863. axisDev.DecelStop((int)AxisName.Axis0);
  864. axisDev.DecelStop((int)AxisName.Axis1);
  865. axisDev.DecelStop((int)AxisName.Axis2);
  866. axisDev.DecelStop((int)AxisName.Axis3);
  867. }
  868. /// <summary>
  869. /// 获取脉冲对应的mm距离
  870. /// </summary>
  871. /// <param name="axis"></param>
  872. /// <returns></returns>
  873. public int GetMMtoPlus(AxisName axis)
  874. {
  875. switch (axis)
  876. {
  877. case AxisName.Axis0:
  878. return HomeParamsX1.MM2PulseNum;
  879. case AxisName.Axis1:
  880. return HomeParamsX2.MM2PulseNum;
  881. case AxisName.Axis2:
  882. return HomeParamsY.MM2PulseNum;
  883. case AxisName.Axis3:
  884. return HomeParamsZ.MM2PulseNum;
  885. default: return 1;
  886. }
  887. }
  888. /// <summary>
  889. /// I/O指令输出
  890. /// </summary>
  891. /// <param name="processParam"></param>
  892. /// <param name="isStrobe">频闪</param>
  893. /// <param name="recover">输出sleep(recoverWaitTime)下,后恢复原信号</param>
  894. /// <param name="recoverWaitTime">sleep 后反转</param>
  895. public bool io_output(string tagName, JObject processParam, bool isStrobe = false, bool recover = false, int recoverWaitTime = 100)
  896. {
  897. bool result = false;
  898. string[] OUT_OP_SHOW = processParam.Value<JArray>("OUT_OP_SHOW").ToObject<List<string>>().ToArray();
  899. OUT_OP_SHOW = IODataFormatBinaryStr(OUT_OP_SHOW, true);
  900. for (int i = 0; i < OUT_OP_SHOW.Length; i++)
  901. {
  902. for (int j = 0; j < OUT_OP_SHOW[i].Length; j++)
  903. {
  904. int jj = OUT_OP_SHOW[i].Length - j - 1;
  905. if (OUT_OP_SHOW[i][jj] == 'L' || OUT_OP_SHOW[i][jj] == 'H')
  906. {
  907. if (recover)
  908. {
  909. if (recoverWaitTime > 0)
  910. {
  911. ioCardDev.WriteBitState(i, j, OUT_OP_SHOW[i][jj] == 'H');
  912. Thread.Sleep(recoverWaitTime);
  913. }
  914. ioCardDev.WriteBitState(i, j, OUT_OP_SHOW[i][jj] == 'L');
  915. }
  916. else
  917. {
  918. ioCardDev.WriteBitState(i, j, OUT_OP_SHOW[i][jj] == 'H');
  919. }
  920. result = true;
  921. }
  922. }
  923. }
  924. return result;
  925. }
  926. /// <summary>
  927. /// 多轴判断到位
  928. /// </summary>
  929. /// <param name="axisList"></param>
  930. /// <returns></returns>
  931. public bool WaitAxisDone(List<int> axisList)
  932. {
  933. foreach (int i in axisList)
  934. {
  935. if (axisDev.CheckDone(i, 30) != 0)
  936. {
  937. return false;
  938. }
  939. }
  940. return true;
  941. }
  942. public bool WaitAllAxisDone()
  943. {
  944. for (int i = 0; i < 4; i++)
  945. {
  946. if (axisDev.CheckDone(i, 30) != 0)
  947. {
  948. return false;
  949. }
  950. }
  951. return true;
  952. }
  953. public double GetAxisPosValueMM(int axisNo)
  954. {
  955. double pos = axisDev.GetFeedbackPos(axisNo);
  956. return pos / (double)GetMMtoPlus((AxisName)axisNo);
  957. }
  958. #endregion
  959. #endregion
  960. #region 公开字段
  961. private bool _isInit;
  962. /// <summary>
  963. /// 是否初始化完成
  964. /// </summary>
  965. public bool IsInit { get { return _isInit; } }
  966. private bool _isRuning;
  967. /// <summary>
  968. /// 设备正在运行
  969. /// </summary>
  970. public bool IsRuning { get { return _isRuning; } }
  971. private bool _isAuto;
  972. /// <summary>
  973. /// 设备正在自动化流程中
  974. /// </summary>
  975. public bool IsAuto { get { return _isAuto; } }
  976. #endregion
  977. #region 用户+登入+管理
  978. /// <summary>
  979. /// 登入
  980. /// </summary>
  981. /// <returns></returns>
  982. public bool LoginSystem()
  983. {
  984. return userMgr.UserLoginDialog();
  985. }
  986. /// <summary>
  987. /// 用户权限
  988. /// </summary>
  989. public void UserPermissiomMgr()
  990. {
  991. userMgr.RightManageDialog();
  992. }
  993. /// <summary>
  994. /// 用户管理
  995. /// </summary>
  996. public void UserListMgr()
  997. {
  998. userMgr.UserManagerDialog();
  999. }
  1000. #endregion
  1001. #region 系统初始化&&运行
  1002. /// <summary>
  1003. /// 系统初始化
  1004. /// </summary>
  1005. /// <returns></returns>
  1006. public bool Initial()
  1007. {
  1008. try
  1009. {
  1010. bool ret = false;
  1011. string err = "";
  1012. InitLog("系统开始初始化...");
  1013. //Thread.Sleep(200);
  1014. // 加载系统配置
  1015. InitLog("加载系统参数...");
  1016. confMgr.ReadSizeDefectItems();
  1017. confMgr.ReadDefectItems();
  1018. ret = confMgr.LoadSystemConfig();
  1019. LightChCount = confMgr.SysConfigParams.LightChannelCnt;
  1020. if (!ret)
  1021. {
  1022. throw new Exception("系统参数加载失败...");
  1023. }
  1024. InitLog("系统参数加载完成!");
  1025. //根据llog路径,开始记录日志
  1026. statusMgr.StartLog(confMgr.SysConfigParams.LogPath);
  1027. statusMgr.GotoInitial();
  1028. SendStatus();
  1029. //Thread.Sleep(200);
  1030. // 硬件初始化
  1031. if (!InitAllDev())
  1032. {
  1033. throw new Exception("硬件初始化失败...");
  1034. }
  1035. InitLog("硬件初始化完成!");
  1036. // 加载硬件配置
  1037. InitLog("加载硬件驱动参数...");
  1038. if (!LoadDevConfig())
  1039. {
  1040. throw new Exception("加载硬件驱动参数失败...");
  1041. }
  1042. InitLog("加载硬件驱动参数完成!");
  1043. //Thread.Sleep(200);
  1044. // 处理运行
  1045. InitLog("AI算法核心初始化...");
  1046. if (!defectLib.start())
  1047. throw new Exception("外观检测核心初始化失败...");
  1048. if (!sizeLib.start(confMgr.SysConfigParams.ImageProcessPath))
  1049. throw new Exception("尺寸检测核心初始化失败...");
  1050. InitLog("AI算法核心初始化完成!");
  1051. InitLog("镜头电机回原...");
  1052. //镜头电机回原
  1053. lensMotorDev.BackHome(0, new HomeVelocityParams());
  1054. lensMotorDev.CheckHomeDone(0, 3000);
  1055. //移动到 4.5X
  1056. //lensMotorDev.MoveAbsPulse(0, new VelocityCurveParams(), (int)SmallAxCmdPos.倍率4_5X);
  1057. //lensMotorDev.CheckDone(0, 5000);
  1058. InitLog("镜头电机回原完成!");
  1059. //移动Axis前等待厚度传感器收回
  1060. InitLog("检测厚度传感器安全值...");
  1061. double TempVal = thicknessDev.GetValue();
  1062. if (TempVal < Math.Abs(confMgr.SysConfigParams.ThicknessSafeValue))
  1063. throw new Exception("厚度传感器不在安全位置!");
  1064. //多轴回原
  1065. if (confMgr.SysConfigParams.OpenAutoGoHome)
  1066. {
  1067. if ((homeParamsZ != null) && (homeParamsX1 != null) && (homeParamsX2 != null) && (homeParamsY != null))
  1068. {
  1069. axisDev.ResetAxisState((int)AxisName.Axis0);
  1070. axisDev.ResetAxisState((int)AxisName.Axis1);
  1071. axisDev.ResetAxisState((int)AxisName.Axis2);
  1072. axisDev.ResetAxisState((int)AxisName.Axis3);
  1073. InitLog("Z轴开始回原点...");
  1074. axisDev.BackHome((int)AxisName.Axis3, homeParamsZ);
  1075. InitLog("X1轴开始回原点...");
  1076. axisDev.BackHome((int)AxisName.Axis0, homeParamsX1);
  1077. InitLog("X2轴开始回原点...");
  1078. axisDev.BackHome((int)AxisName.Axis1, homeParamsX2);
  1079. InitLog("Y轴开始回原点...");
  1080. //axisDev.BackHome((int)AxisName.Axis1, homeParamsY);
  1081. //y轴使用io回原
  1082. if (!AxisYGoHome())
  1083. throw new Exception("Y轴回原报警!");
  1084. }
  1085. Thread.Sleep(1000);
  1086. //判断轴是否回原成功
  1087. if (!AxisYGoHomeDone(60))
  1088. {
  1089. AxisAllImmediateStop();
  1090. throw new Exception("Y轴回原失败!");
  1091. }
  1092. if (axisDev.CheckHomeDone((int)AxisName.Axis0, 60) != 0)
  1093. {
  1094. AxisAllImmediateStop();
  1095. throw new Exception("X1轴回原失败!");
  1096. }
  1097. if (axisDev.CheckHomeDone((int)AxisName.Axis1, 60) != 0)
  1098. {
  1099. AxisAllImmediateStop();
  1100. throw new Exception("X2轴回原失败!");
  1101. }
  1102. if (axisDev.CheckHomeDone((int)AxisName.Axis3, 60) != 0)
  1103. {
  1104. AxisAllImmediateStop();
  1105. throw new Exception("Z轴回原失败!");
  1106. }
  1107. InitLog("所有轴回原成功!");
  1108. //清空y轴发送命令和反馈位置
  1109. axisDev.SetCommandPos((int)AxisName.Axis2, 0);
  1110. axisDev.SetFeedbackPos((int)AxisName.Axis2, 0);
  1111. //X轴标定启用
  1112. if(confMgr.SysConfigParams.OpenAxisXCalibration)
  1113. {
  1114. OpenAxisXCal();
  1115. }
  1116. }
  1117. LedReady();
  1118. if (confMgr.SysConfigParams.OpenAutoGoHome)
  1119. {
  1120. InitLog("移动到上料...");
  1121. //Thread.Sleep(500);
  1122. if (!GotoLoadPos())
  1123. {
  1124. throw new Exception("移动到上料失败!");
  1125. }
  1126. }
  1127. //初始化成功
  1128. _isInit = true;
  1129. statusMgr.GotoNormalStandby();
  1130. SendStatus();
  1131. OnInitRuning(new InitEventArgs("系统初始化完成...", this.IsInit));
  1132. Run();
  1133. return ret;
  1134. }
  1135. catch (Exception ex)
  1136. {
  1137. InitLog(ex.Message, "初始化", WarningEnum.High);
  1138. InitLog("系统初始化失败!" , "初始化", WarningEnum.High);
  1139. //statusMgr.GotoWarning(MaiMuControl.Device.WarningEnum.High, "初始化", ex.Message);
  1140. return false;
  1141. }
  1142. }
  1143. /// <summary>
  1144. /// 初始化图像处理报警
  1145. /// </summary>
  1146. /// <returns></returns>
  1147. public bool InitDefectEvent()
  1148. {
  1149. defectLib.WarningEvent = (warning, msg) =>
  1150. {
  1151. Log("缺陷处理", msg, warning);
  1152. };
  1153. sizeLib.WarningEvent = (warning, msg) =>
  1154. {
  1155. Log("尺寸检测", msg, warning);
  1156. };
  1157. return true;
  1158. }
  1159. /// <summary>
  1160. /// 开启修复台web服务器
  1161. /// </summary>
  1162. /// <returns></returns>
  1163. public bool InitWebServer()
  1164. {
  1165. //InitLog("开启数据服务器...");
  1166. webService.Defect_Compress_SavePath = confMgr.SysConfigParams.DefectRepairImag.SavePath;
  1167. webService.SizeBmp_Zoom_Image_SavePath = confMgr.SysConfigParams.SizeRepairImag.SavePath;
  1168. webService.LogEvent = (warning, msg) =>
  1169. {
  1170. Log("HTTP服务", msg, warning);
  1171. //OnMainRuning(new MainEventArgs("HTTP服务", msg, warning));
  1172. if(!confMgr.SysConfigParams.OpenHttpLog)
  1173. webService.LogEvent = null;
  1174. };
  1175. webService.start(confMgr.SysConfigParams.HttpServerIP, confMgr.SysConfigParams.HttpServerPort);
  1176. //InitLog("开启数据服务器完成!");
  1177. Thread.Sleep(200);
  1178. return true;
  1179. }
  1180. public bool InitCloudConnect()
  1181. {
  1182. if (confMgr.SysConfigParams.OpenCloud)
  1183. {
  1184. if (cloudMgr.ConnectCloud(confMgr.SysConfigParams.CloudServerIP, confMgr.SysConfigParams.CloudServerPort,
  1185. confMgr.SysConfigParams.CloudUser, confMgr.SysConfigParams.CloudPassword))
  1186. {
  1187. init_Cloud = true;
  1188. Log("云端数据", "开启云端连接");
  1189. return true;
  1190. }
  1191. Log("云端数据", "云端连接失败!", WarningEnum.Low);
  1192. return false;
  1193. }
  1194. return true;
  1195. }
  1196. /// <summary>
  1197. /// 运行主线程
  1198. /// </summary>
  1199. private void Run()
  1200. {
  1201. _mainThread = new Thread(() =>
  1202. {
  1203. MainThreadFunction();
  1204. });
  1205. _mainThread.IsBackground = true;
  1206. _mainThread.Start();
  1207. }
  1208. #endregion
  1209. #region 系统关闭
  1210. /// <summary>
  1211. /// 关闭
  1212. /// </summary>
  1213. public void Close()
  1214. {
  1215. _isInit = false;
  1216. _isRuning = false;
  1217. if (null != _cts)
  1218. {
  1219. _cts.Cancel();
  1220. }
  1221. if (null != _mainThread)
  1222. {
  1223. _mainThread.Join(1000);
  1224. }
  1225. webService.stop();
  1226. AxisDStop();
  1227. axisDev.SetServo((int)AxisName.Axis0, 0);
  1228. axisDev.SetServo((int)AxisName.Axis1, 0);
  1229. axisDev.SetServo((int)AxisName.Axis2, 0);
  1230. axisDev.SetServo((int)AxisName.Axis3, 0);
  1231. axisDev.CloseBoard();
  1232. //关闭相机
  1233. camDevFront.CloseCamera();
  1234. camDevBack.CloseCamera();
  1235. //关闭光源
  1236. for (int i = 0; i < LightChCount; i++)
  1237. {
  1238. lightDev.CloseLight(i + 1);
  1239. }
  1240. //lightDev.CloseLight((int)LightChannelEnum.CH1);
  1241. //lightDev.CloseLight((int)LightChannelEnum.CH2);
  1242. //lightDev.CloseLight((int)LightChannelEnum.CH3);
  1243. //lightDev.CloseLight((int)LightChannelEnum.CH4);
  1244. //lightDev.CloseLight((int)LightChannelEnum.CH5);
  1245. //lightDev.CloseLight((int)LightChannelEnum.CH6);
  1246. lightDev.CloseDev();
  1247. //关闭传感器
  1248. thicknessDev.CloseDev();
  1249. tensionDev.CloseDev();
  1250. lensMotorDev.CloseBoard();
  1251. //关闭io
  1252. ioCardDev.ResetAllDO();
  1253. ioCardDev.CloseBoard();
  1254. }
  1255. #endregion
  1256. #region 产品管理
  1257. public string SelectProduct()
  1258. {
  1259. InputFrm frm = new InputFrm(productCodeList, "请选择产品料号:");
  1260. if (frm.ShowDialog() != DialogResult.OK && string.IsNullOrWhiteSpace(frm.inputData))
  1261. return "";
  1262. //显示料号
  1263. //this.txtProductCode.Text = frm.inputData;
  1264. var model = PdtService.GetModelNav(frm.inputData);
  1265. if (model != null && model.StepInfo.ProcessList.Count > 0)
  1266. {
  1267. //名称料号显示一个就可以
  1268. return model.Code;
  1269. }
  1270. return "";
  1271. }
  1272. /// <summary>
  1273. /// 拷贝产品
  1274. /// </summary>
  1275. /// <param name="list"></param>
  1276. /// <param name="liIndex"></param>
  1277. /// <param name="stepID">流程ID</param>
  1278. /// <param name="stepInfo">流程</param>
  1279. /// <returns></returns>
  1280. public bool ProductCopy(List<Product> list, int liIndex, int stepID, Step stepInfo)
  1281. {
  1282. Product newProduct = new Product()
  1283. {
  1284. Code = list[liIndex].Code + "_clone",
  1285. Name = $"{list[liIndex].Name} (克隆)",
  1286. Spec = list[liIndex].Spec,
  1287. ClassesId = list[liIndex].ClassesId,
  1288. ClassesInfo = list[liIndex].ClassesInfo,
  1289. HoleCount = list[liIndex].HoleCount,
  1290. DefectModelFile = list[liIndex].DefectModelFile,
  1291. AttachmentList = new List<Attachment>(),
  1292. BatchId = list[liIndex].BatchId,
  1293. TargetCount = list[liIndex].TargetCount,
  1294. CompleteCount = list[liIndex].CompleteCount,
  1295. BatchHistoryList = new List<BatchHistory>(),
  1296. QualifiedCriterionList = new List<QualifiedCriterion>(),
  1297. Note = list[liIndex].Note,
  1298. TensionBaseValue = list[liIndex].TensionBaseValue,
  1299. TensionUpFloatValue = list[liIndex].TensionUpFloatValue,
  1300. TensionDownFloatValue = list[liIndex].TensionDownFloatValue,
  1301. HeightBaseValue = list[liIndex].HeightBaseValue,
  1302. HeightUpFloatValue = list[liIndex].HeightUpFloatValue,
  1303. HeightDownFloatValue = list[liIndex].HeightDownFloatValue,
  1304. LineWidthBaseValue = list[liIndex].LineWidthBaseValue,
  1305. LineWidthUpFloatValue = list[liIndex].LineWidthUpFloatValue,
  1306. LineWidthDownFloatValue = list[liIndex].LineWidthDownFloatValue,
  1307. PTBaseValue = list[liIndex].PTBaseValue,
  1308. PTUpFloatValue = list[liIndex].PTUpFloatValue,
  1309. PTDownFloatValue = list[liIndex].PTDownFloatValue,
  1310. HeightBaseDec = list[liIndex].HeightBaseDec,
  1311. StepId = stepID,
  1312. StepInfo = stepInfo,
  1313. ProductProcessList = new List<ProductProcess>(),
  1314. ReviseStepId = list[liIndex].ReviseStepId,
  1315. ReviseStepInfo = list[liIndex].ReviseStepInfo,
  1316. ProductReviseProcessList = new List<ProductReviseProcess>(),
  1317. AssistStepId = list[liIndex].AssistStepId,
  1318. AssistStepInfo = list[liIndex].AssistStepInfo,
  1319. ProductAssistProcessList = new List<ProductAssistProcess>(),
  1320. //OrderList = new List<Order>(),
  1321. ModifyUserCode = userMgr.LoginUser.Code,
  1322. CreateUserCode = userMgr.LoginUser.Code
  1323. };
  1324. foreach (var item in list[liIndex].AttachmentList)
  1325. {
  1326. newProduct.AttachmentList.Add(new Attachment()
  1327. {
  1328. TBName = item.TBName,
  1329. Type = item.Type,
  1330. Pid = item.Pid,
  1331. Name = item.Name,
  1332. NameTimestamp = item.NameTimestamp,
  1333. ExtendName = item.ExtendName,
  1334. ModifyUserCode = userMgr.LoginUser.Code,
  1335. CreateUserCode = userMgr.LoginUser.Code
  1336. });
  1337. }
  1338. foreach (var item in list[liIndex].BatchHistoryList)
  1339. {
  1340. newProduct.BatchHistoryList.Add(new BatchHistory()
  1341. {
  1342. Pid = item.Pid,
  1343. BatchId = item.BatchId,
  1344. TargetCount = item.TargetCount,
  1345. CompleteCount = item.CompleteCount,
  1346. ModifyUserCode = userMgr.LoginUser.Code,
  1347. CreateUserCode = userMgr.LoginUser.Code
  1348. });
  1349. }
  1350. foreach (var item in list[liIndex].QualifiedCriterionList)
  1351. {
  1352. newProduct.QualifiedCriterionList.Add(new QualifiedCriterion()
  1353. {
  1354. Pid = item.Pid,
  1355. DefectCode = item.DefectCode,
  1356. Size = item.Size,
  1357. MaxDefectCount = item.MaxDefectCount,
  1358. ModifyUserCode = userMgr.LoginUser.Code,
  1359. CreateUserCode = userMgr.LoginUser.Code
  1360. });
  1361. }
  1362. foreach (var item in list[liIndex].ProductProcessList)
  1363. {
  1364. newProduct.ProductProcessList.Add(new ProductProcess()
  1365. {
  1366. Pid = item.Pid,
  1367. ProcessCode = item.ProcessCode,
  1368. ProcessParams = item.ProcessParams,
  1369. ModifyUserCode = userMgr.LoginUser.Code,
  1370. CreateUserCode = userMgr.LoginUser.Code
  1371. });
  1372. }
  1373. foreach (var item in list[liIndex].ProductReviseProcessList)
  1374. {
  1375. newProduct.ProductReviseProcessList.Add(new ProductReviseProcess()
  1376. {
  1377. Pid = item.Pid,
  1378. ProcessCode = item.ProcessCode,
  1379. ProcessParams = item.ProcessParams,
  1380. ModifyUserCode = userMgr.LoginUser.Code,
  1381. CreateUserCode = userMgr.LoginUser.Code
  1382. });
  1383. }
  1384. foreach (var item in list[liIndex].ProductAssistProcessList)
  1385. {
  1386. newProduct.ProductAssistProcessList.Add(new ProductAssistProcess()
  1387. {
  1388. Pid = item.Pid,
  1389. ProcessCode = item.ProcessCode,
  1390. ProcessParams = item.ProcessParams,
  1391. ModifyUserCode = userMgr.LoginUser.Code,
  1392. CreateUserCode = userMgr.LoginUser.Code
  1393. });
  1394. }
  1395. /*
  1396. foreach (var item in list[liIndex].OrderList)
  1397. {
  1398. newProduct.OrderList.Add(new Order()
  1399. {
  1400. ProductId = item.ProductId,
  1401. ProductInfo = item.ProductInfo,
  1402. SN = item.SN,
  1403. ModifyUserCode = Config.loginUser.Code,
  1404. CreateUserCode = Config.loginUser.Code
  1405. });
  1406. }*/
  1407. bool result = PdtService.InsertNav(newProduct);
  1408. return result;
  1409. }
  1410. /// <summary>
  1411. /// 加载产品列表
  1412. /// </summary>
  1413. public void LoadProductCodeList()
  1414. {
  1415. try
  1416. {
  1417. productCodeList = PdtService.GetList().Select(m => m.Code).ToList();
  1418. productIdList = PdtService.GetList().Select(m => m.Id).ToList();
  1419. //string[] array = ReadSNText();
  1420. //if (array != null && array.Length > 0)
  1421. //{
  1422. // for (int i = 0; i < array.Length; i++)
  1423. // productSNList.Add(array[i]);
  1424. //}
  1425. }
  1426. catch (Exception ex)
  1427. {
  1428. //throw new Exception("加载产品料号失败:" + ex.Message);
  1429. OnMainRuning(new MainEventArgs("启动", "加载产品料号失败:" + ex.Message, WarningEnum.High));
  1430. statusMgr.GotoWarning(WarningEnum.High, "启动", "加载产品料号失败:" + ex.Message);
  1431. SendStatus();
  1432. }
  1433. }
  1434. /// <summary>
  1435. /// 记录使用的sn
  1436. /// </summary>
  1437. /// <param name="str"></param>
  1438. public void Remind(string str)
  1439. {
  1440. string workPath = Directory.GetCurrentDirectory();
  1441. string textPath = Path.Combine(workPath, "TextRemind.txt");
  1442. try
  1443. {
  1444. if (productSNList.Count == 0 || !productSNList.Contains(str))
  1445. {
  1446. if (productSNList.Count > 20)
  1447. productSNList.RemoveAt(0);
  1448. productSNList.Add(str);
  1449. //File.AppendAllLines(textPath, new string[] { str });
  1450. }
  1451. if(productSNList.Count > 0)
  1452. {
  1453. File.WriteAllLines(textPath, productSNList);
  1454. }
  1455. }
  1456. catch
  1457. {
  1458. }
  1459. }
  1460. /// <summary>
  1461. /// 读取近期sn
  1462. /// </summary>
  1463. /// <returns></returns>
  1464. private string[] ReadSNText()
  1465. {
  1466. string workPath = Directory.GetCurrentDirectory();
  1467. string textPath = Path.Combine(workPath, "TextRemind.txt");
  1468. try
  1469. {
  1470. if (!File.Exists(textPath))
  1471. return null;
  1472. return File.ReadAllLines(textPath);
  1473. }
  1474. catch
  1475. {
  1476. return null;
  1477. }
  1478. }
  1479. #endregion
  1480. #region 流程步骤
  1481. private static void InitDevDic()
  1482. {
  1483. //旧版流程
  1484. //dicDevType.Add("CodeScanner", "扫码枪");//固定为必有开始
  1485. if (!dicDevType.ContainsKey("IOCard")) dicDevType.Add("IOCard", "I/O控制");
  1486. //if (!dicDevType.ContainsKey("Tension")) dicDevType.Add("Tension", "张力测量");
  1487. if (!dicDevType.ContainsKey("Height")) dicDevType.Add("Height", "厚度测量");
  1488. if (!dicDevType.ContainsKey("Axis")) dicDevType.Add("Axis", "滑台电机");
  1489. if (!dicDevType.ContainsKey("AxisTag")) dicDevType.Add("AxisTag", "滑台&测量");
  1490. if (!dicDevType.ContainsKey("Light")) dicDevType.Add("Light", "光源");
  1491. if (!dicDevType.ContainsKey("Scanner_CC")) dicDevType.Add("Scanner_CC", "前部相机拍照");
  1492. if (!dicDevType.ContainsKey("Scanner_GENTL")) dicDevType.Add("Scanner_GENTL", "后部相机拍照");
  1493. if (!dicDevType.ContainsKey("SmallAxis")) dicDevType.Add("SmallAxis", "镜头电机");
  1494. if (!dicDevType.ContainsKey("Defect")) dicDevType.Add("Defect", "缺陷检测");
  1495. if (!dicDevType.ContainsKey("Size")) dicDevType.Add("Size", "尺寸测量");
  1496. if (!dicDevType.ContainsKey("For")) dicDevType.Add("For", "For循环");
  1497. if (!dicDevType.ContainsKey("If")) dicDevType.Add("If", "If条件");
  1498. //新版流程
  1499. if (!ProcessType.ContainsKey("Tension")) ProcessType.Add("Tension", "张力测量");
  1500. if (!ProcessType.ContainsKey("Height")) ProcessType.Add("Height", "厚度测量");
  1501. if (!ProcessType.ContainsKey("LensMotor")) ProcessType.Add("LensMotor", "镜头变焦");
  1502. if (!ProcessType.ContainsKey("Light")) ProcessType.Add("Light", "光源设置");
  1503. if (!ProcessType.ContainsKey("Mark")) ProcessType.Add("Mark", "Mark检测");
  1504. if (!ProcessType.ContainsKey("PointTest")) ProcessType.Add("PointTest", "尺寸检测");
  1505. if (!ProcessType.ContainsKey("SizeAndDefect")) ProcessType.Add("SizeAndDefect", "外观检测");
  1506. if (!ProcessType.ContainsKey("For")) ProcessType.Add("For", "测试循环");
  1507. }
  1508. #endregion
  1509. #region 操作
  1510. #region webLogg
  1511. public void CheckWebLog()
  1512. {
  1513. if (!confMgr.SysConfigParams.OpenHttpLog)
  1514. webService.LogEvent = null;
  1515. else
  1516. {
  1517. webService.LogEvent = (warning, msg) =>
  1518. {
  1519. Log("HTTP服务", msg, warning);
  1520. //OnMainRuning(new MainEventArgs("HTTP服务", msg, warning));
  1521. };
  1522. }
  1523. }
  1524. #endregion
  1525. #region 上料移动
  1526. /// <summary>
  1527. /// 关闭光源移动到上料位置
  1528. /// </summary>
  1529. /// <returns></returns>
  1530. public bool GotoLoadPos()
  1531. {
  1532. bool ret = true;
  1533. //关闭光源
  1534. for (int i = 0; i < LightChCount; i++)
  1535. {
  1536. lightDev.CloseLight(i + 1);
  1537. }
  1538. VelocityCurveParams vel_z = new VelocityCurveParams(DefaultSpeed / 2, DefaultSpeed / 2, 0, DefaultSpeed / 2, 1, GetMMtoPlus(AxisName.Axis3));
  1539. axisDev.MoveAbsValue((int)AxisName.Axis3, vel_z, confMgr.LoadPoint_Z);
  1540. if (axisDev.CheckDone((int)AxisName.Axis3, 30) != 0)
  1541. return false;
  1542. VelocityCurveParams vel_x1 = new VelocityCurveParams(DefaultSpeed, DefaultSpeed, 0, DefaultSpeed, 1, GetMMtoPlus(AxisName.Axis0));
  1543. axisDev.MoveAbsValue((int)AxisName.Axis0, vel_x1, confMgr.LoadPoint_X1);
  1544. VelocityCurveParams vel_x2 = new VelocityCurveParams(DefaultSpeed, DefaultSpeed, 0, DefaultSpeed, 1, GetMMtoPlus(AxisName.Axis1));
  1545. axisDev.MoveAbsValue((int)AxisName.Axis1, vel_x2, confMgr.LoadPoint_X2);
  1546. VelocityCurveParams vel_y = new VelocityCurveParams(DefaultSpeed, DefaultSpeed, 0, DefaultSpeed, 1, GetMMtoPlus(AxisName.Axis2));
  1547. axisDev.MoveAbsValue((int)AxisName.Axis2, vel_y, confMgr.LoadPoint_Y);
  1548. if (axisDev.CheckDone((int)AxisName.Axis0, 30) != 0)
  1549. return false;
  1550. if (axisDev.CheckDone((int)AxisName.Axis1, 30) != 0)
  1551. return false;
  1552. if (axisDev.CheckDone((int)AxisName.Axis2, 30) != 0)
  1553. return false;
  1554. return ret;
  1555. }
  1556. #endregion
  1557. #region 急停
  1558. /// <summary>
  1559. /// 急停设备
  1560. /// </summary>
  1561. public void EmergencyStop()
  1562. {
  1563. Log("设备", "紧急停止", WarningEnum.High);
  1564. _isAuto = false;
  1565. AxisAllImmediateStop();
  1566. }
  1567. #endregion
  1568. #region IO气缸
  1569. private int GetIOPortIndex(int DIDOEnum)
  1570. {
  1571. return DIDOEnum / 8;
  1572. }
  1573. private int GetIOBitIndex(int DIDOEnum)
  1574. {
  1575. return DIDOEnum % 8;
  1576. }
  1577. /// <summary>
  1578. /// 开关照明灯
  1579. /// </summary>
  1580. /// <param name="open"></param>
  1581. public void OpenFloodlight(bool open)
  1582. {
  1583. ////记录日产量
  1584. //if (confMgr.SetDailyOutputAdd(out DailyOutput))
  1585. //{
  1586. // SendDailyOutput();
  1587. //}
  1588. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.日光灯), GetIOBitIndex((int)DOName.日光灯), open);
  1589. }
  1590. /// <summary>
  1591. /// 产品夹紧气缸控制
  1592. /// </summary>
  1593. /// <param name="ack"></param>
  1594. /// <returns></returns>
  1595. public bool RunQG(bool ack)
  1596. {
  1597. bool ret;
  1598. ret = ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.加紧气缸), GetIOBitIndex((int)DOName.加紧气缸), ack);
  1599. Thread.Sleep(500);
  1600. //ret = ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.加紧气缸), GetIOBitIndex((int)DOName.加紧气缸), ack);
  1601. return ret;
  1602. }
  1603. /// <summary>
  1604. /// 获取加紧气缸IO状态
  1605. /// </summary>
  1606. /// <returns></returns>
  1607. public bool QGSts()
  1608. {
  1609. bool sts;
  1610. ioCardDev.GetDOBitState(GetIOPortIndex((int)DOName.加紧气缸), GetIOBitIndex((int)DOName.加紧气缸), out sts);
  1611. return sts;
  1612. }
  1613. /// <summary>
  1614. /// 测厚气缸控制
  1615. /// </summary>
  1616. /// <param name="ack"></param>
  1617. /// <returns></returns>
  1618. public bool RunThickness(bool ack)
  1619. {
  1620. bool ret;
  1621. ret = ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), ack);
  1622. Thread.Sleep(500);
  1623. return ret;
  1624. }
  1625. /// <summary>
  1626. /// 获取测厚气缸IO状态
  1627. /// </summary>
  1628. /// <returns></returns>
  1629. public bool ThicknessSts()
  1630. {
  1631. bool sts;
  1632. ioCardDev.GetDOBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), out sts);
  1633. return sts;
  1634. }
  1635. #endregion
  1636. #region 测厚安全
  1637. /// <summary>
  1638. /// 判断测厚气缸是否在安全位置
  1639. /// </summary>
  1640. /// <returns></returns>
  1641. public bool ThicknessIsSafe()
  1642. {
  1643. //RunThickness(false);
  1644. bool sts;
  1645. ioCardDev.GetDOBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), out sts);
  1646. if(sts)
  1647. return false;
  1648. if (thicknessDev.GetValue() < Math.Abs(confMgr.SysConfigParams.ThicknessSafeValue))
  1649. return false;
  1650. return true;
  1651. }
  1652. #endregion
  1653. #region 三色灯
  1654. /// <summary>
  1655. /// 三色灯初始化
  1656. /// </summary>
  1657. public void LedReady()
  1658. {
  1659. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  1660. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), false);
  1661. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), false);
  1662. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  1663. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  1664. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.复位按钮黄灯), GetIOBitIndex((int)DOName.复位按钮黄灯), false);
  1665. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), false);
  1666. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  1667. }
  1668. /// <summary>
  1669. /// 运行状态三色灯
  1670. /// </summary>
  1671. public void LedRun()
  1672. {
  1673. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), true);
  1674. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), false);
  1675. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), false);
  1676. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  1677. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), true);
  1678. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.复位按钮黄灯), GetIOBitIndex((int)DOName.复位按钮黄灯), false);
  1679. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), false);
  1680. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  1681. }
  1682. /// <summary>
  1683. /// 暂停状态三色灯
  1684. /// </summary>
  1685. public void LedPause()
  1686. {
  1687. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  1688. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), false);
  1689. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), true);
  1690. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  1691. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  1692. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.复位按钮黄灯), GetIOBitIndex((int)DOName.复位按钮黄灯), false);
  1693. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), true);
  1694. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  1695. }
  1696. //控制黄灯闪烁
  1697. private bool Blink;
  1698. private int BlinkCnt = 0;
  1699. //控制蜂鸣间隔
  1700. private int BuzzCnt = 0;
  1701. /// <summary>
  1702. /// 回原状态三色灯
  1703. /// </summary>
  1704. /// <param name="val"></param>
  1705. public void LedRset(bool val)
  1706. {
  1707. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  1708. //ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), val);
  1709. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), false);
  1710. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  1711. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  1712. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.复位按钮黄灯), GetIOBitIndex((int)DOName.复位按钮黄灯), val);
  1713. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), false);
  1714. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  1715. Blink = val;
  1716. BlinkCnt = 0;
  1717. }
  1718. #endregion
  1719. #region 轴回原
  1720. /// <summary>
  1721. /// 启用X轴标定
  1722. /// </summary>
  1723. private void OpenAxisXCal()
  1724. {
  1725. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.X1回原), GetIOBitIndex((int)DOName.X1回原), true);
  1726. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.X2回原), GetIOBitIndex((int)DOName.X2回原), true);
  1727. Thread.Sleep(300);
  1728. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.X1回原), GetIOBitIndex((int)DOName.X1回原), false);
  1729. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.X2回原), GetIOBitIndex((int)DOName.X2回原), false);
  1730. }
  1731. /// <summary>
  1732. /// Y轴回原,使用信号回原,因为驱动器中有标定参数需要驱动器控制回原才起效
  1733. /// </summary>
  1734. /// <returns></returns>
  1735. private bool AxisYGoHome()
  1736. {
  1737. //加入读取急停信号
  1738. AxisSignalState axisSignalState = axisDev.GetAxisState((int)AxisName.Axis2);
  1739. if(axisSignalState.EMG != GeneralElectricalLevelMode.High)
  1740. {
  1741. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.Y轴回原点), GetIOBitIndex((int)DOName.Y轴回原点), true);
  1742. return true;
  1743. }
  1744. return false;
  1745. }
  1746. /// <summary>
  1747. /// 判断y轴是否回原
  1748. /// </summary>
  1749. /// <param name="timeout"></param>
  1750. /// <returns></returns>
  1751. private bool AxisYGoHomeDone(double timeout)
  1752. {
  1753. System.Diagnostics.Stopwatch strtime = new System.Diagnostics.Stopwatch();
  1754. strtime.Start();
  1755. do
  1756. {
  1757. //加入读取急停信号
  1758. AxisSignalState axisSignalState = axisDev.GetAxisState((int)AxisName.Axis2);
  1759. if (axisSignalState.EMG == GeneralElectricalLevelMode.High)
  1760. {
  1761. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.Y轴回原点), GetIOBitIndex((int)DOName.Y轴回原点), false);
  1762. return false;
  1763. }
  1764. //判断是否正常停止
  1765. bool sts;
  1766. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.Y轴回原点完成), GetIOBitIndex((int)DIName.Y轴回原点完成), out sts);
  1767. if (sts)
  1768. break;
  1769. //检查是否超时
  1770. strtime.Stop();
  1771. if (strtime.ElapsedMilliseconds / 1000.0 > timeout)
  1772. {
  1773. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.Y轴回原点), GetIOBitIndex((int)DOName.Y轴回原点), false);
  1774. return false;
  1775. }
  1776. strtime.Start();
  1777. //延时
  1778. System.Threading.Thread.Sleep(20);
  1779. } while (true);
  1780. Thread.Sleep(500);
  1781. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.Y轴回原点), GetIOBitIndex((int)DOName.Y轴回原点), false);
  1782. return true;
  1783. }
  1784. #endregion
  1785. #region 上料位
  1786. public bool GotoReadyPosAndIO()
  1787. {
  1788. Log("复位", "系统复位");
  1789. _isAuto = false;
  1790. CurrProcessIndex = -1;
  1791. CurrPoinntCount = 0;
  1792. CurrStepResult = 0;
  1793. if(!RunThickness(false))
  1794. {
  1795. Log("复位", "测厚气缸复位失败", WarningEnum.High);
  1796. return false;
  1797. }
  1798. bool ret = GotoLoadPos();
  1799. if (!ret)
  1800. {
  1801. Log("复位", "系统电机复位失败", WarningEnum.High);
  1802. return false;
  1803. }
  1804. if (!RunQG(false))
  1805. {
  1806. Log("复位", "加紧气缸复位失败", WarningEnum.High);
  1807. return false;
  1808. }
  1809. LedReady();
  1810. statusMgr.GotoNormalStandby();
  1811. SendStatus();
  1812. Log("复位", "复位完成");
  1813. return ret;
  1814. }
  1815. /// <summary>
  1816. /// 确认当前位置为上料位置
  1817. /// </summary>
  1818. /// <returns></returns>
  1819. private bool CheckPosIsLoadPos()
  1820. {
  1821. bool ret = false;
  1822. double x1 = GetAxisPosValueMM((int)AxisName.Axis0);
  1823. double x2 = GetAxisPosValueMM((int)AxisName.Axis1);
  1824. double y = GetAxisPosValueMM((int)AxisName.Axis2);
  1825. double z = GetAxisPosValueMM((int)AxisName.Axis3);
  1826. ret = Math.Abs(x1 - confMgr.LoadPoint_X1) < 1;
  1827. ret = ret & Math.Abs(x2 - confMgr.LoadPoint_X2) < 1;
  1828. ret = ret & Math.Abs(y - confMgr.LoadPoint_Y) < 1;
  1829. ret = ret & Math.Abs(z - confMgr.LoadPoint_Z) < 1;
  1830. return ret;
  1831. }
  1832. #endregion
  1833. #region 张力操作
  1834. /// <summary>
  1835. /// 读取张力数据
  1836. /// </summary>
  1837. /// <returns></returns>
  1838. public double TensionGetValue(out TensionResult tensionResult)
  1839. {
  1840. tensionResult = new TensionResult(0, 0, 0, Color.Empty, Color.Empty, Color.Empty);
  1841. if (confMgr.SysConfigParams.DisableTensor)
  1842. {
  1843. Log("张力读取", "张力设备禁用,忽略此步骤!");
  1844. return -1;
  1845. }
  1846. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.触发张力按钮灯), GetIOBitIndex((int)DOName.触发张力按钮灯), true);
  1847. double tensionValue = 0;
  1848. for (int i = 0; i < 5; i++)
  1849. {
  1850. tensionValue = tensionDev.GetValue() + confMgr.SysConfigParams.Tension_Offset;//加入张力偏差
  1851. tensionValue = Math.Round(tensionValue, 2);//保留2位小数
  1852. if (tensionValue >= 0)
  1853. break;
  1854. }
  1855. if (tensionValue < 0)
  1856. {
  1857. Log("张力读取", "张力读取失败,忽略此次测试!");
  1858. return -1;
  1859. }
  1860. Log("张力读取", $"张力值:{tensionValue}");
  1861. Thread.Sleep(500);
  1862. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.触发张力按钮灯), GetIOBitIndex((int)DOName.触发张力按钮灯), false);
  1863. lstTension.Add(tensionValue);
  1864. if (lstTension.Count == 1)
  1865. order.Tension1 = tensionValue;
  1866. else if (lstTension.Count == 2)
  1867. order.Tension2 = tensionValue;
  1868. else if (lstTension.Count == 3)
  1869. order.Tension3 = tensionValue;
  1870. else if (lstTension.Count == 4)
  1871. order.Tension4 = tensionValue;
  1872. else if (lstTension.Count == 5)
  1873. order.Tension5 = tensionValue;
  1874. //TensionResult tensionResult;
  1875. if (CurrProductModel != null)
  1876. updateTensionValue(CurrProductModel.TensionBaseValue + CurrProductModel.TensionUpFloatValue, CurrProductModel.TensionBaseValue - CurrProductModel.TensionDownFloatValue, out tensionResult);
  1877. return tensionValue;
  1878. }
  1879. /// <summary>
  1880. /// 新流程联动读取张力
  1881. /// </summary>
  1882. /// <returns></returns>
  1883. public double TensionGetValueNewStep()
  1884. {
  1885. double tensionValue = 0;
  1886. for (int cnt = 0; cnt < 2; cnt++)
  1887. {
  1888. for (int i = 0; i < 10; i++)
  1889. {
  1890. tensionValue = tensionDev.GetValue() + confMgr.SysConfigParams.Tension_Offset;//加入张力偏差
  1891. tensionValue = Math.Round(tensionValue, 2);//保留2位小数
  1892. if (tensionValue >= 0)
  1893. break;
  1894. Thread.Sleep(50);
  1895. }
  1896. //成功读取跳出循环
  1897. if (tensionValue >= 0)
  1898. break;
  1899. else
  1900. {
  1901. //重连
  1902. tensionDev.CloseDev();
  1903. Thread.Sleep(100);
  1904. if (tensionDev.OpenDevByCom(confMgr.SysConfigParams.TensionCom, confMgr.SysConfigParams.TensionComBaud) < 0)
  1905. {
  1906. Log("张力传感器重连失败!", "重连", WarningEnum.High);
  1907. return -10;
  1908. }
  1909. }
  1910. }
  1911. if (tensionValue < 0)
  1912. {
  1913. return -1;
  1914. }
  1915. return tensionValue;
  1916. }
  1917. public class TensionResult
  1918. {
  1919. public double value = 0;
  1920. public double valueMax = 0;
  1921. public double valueMin = 0;
  1922. public Color color = Color.Empty;
  1923. public Color colorMax = Color.Empty;
  1924. public Color colorMin = Color.Empty;
  1925. public TensionResult(double val, double valMax, double valMin, Color clr, Color clrMax, Color clrMin) {
  1926. value = val; valueMax = valMax; valueMin = valMin; color = clr; colorMax = clrMax; colorMin = clrMin;
  1927. }
  1928. }
  1929. private void updateTensionValue(double upperLimit, double lowerLimit, out TensionResult tensionResult)
  1930. {
  1931. int count = lstTension.Count();
  1932. tensionResult = new TensionResult(0,0,0, Color.Empty, Color.Empty, Color.Empty);
  1933. if (count < 1) return;
  1934. switch (count)
  1935. {
  1936. case 1:
  1937. order.Tension1 = lstTension[count - 1];
  1938. Log("张力值", $"张力1:{order.Tension1}");
  1939. break;
  1940. case 2:
  1941. order.Tension2 = lstTension[count - 1];
  1942. Log("张力值", $"张力2:{order.Tension2}");
  1943. break;
  1944. case 3:
  1945. order.Tension3 = lstTension[count - 1];
  1946. Log("张力值", $"张力3:{order.Tension3}");
  1947. break;
  1948. case 4:
  1949. order.Tension4 = lstTension[count - 1];
  1950. Log("张力值", $"张力4:{order.Tension4}");
  1951. break;
  1952. case 5:
  1953. order.Tension5 = lstTension[count - 1];
  1954. Log("张力值", $"张力5:{order.Tension5}");
  1955. break;
  1956. }
  1957. double value = Math.Round(lstTension.Average(), 2);
  1958. double valueMax = lstTension.Max();
  1959. double valueMin = lstTension.Min();
  1960. if (order != null) order.TensionValue = value;
  1961. Color color = (upperLimit + lowerLimit > 0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
  1962. Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
  1963. Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
  1964. tensionResult = new TensionResult(value, valueMax, valueMin, color, colorMax, colorMin);
  1965. //不合格
  1966. if (color == Color.Red) order.Qualified = false;
  1967. }
  1968. #endregion
  1969. #region 修复台照片删除
  1970. /// <summary>
  1971. /// 删除修复台重复sn图片
  1972. /// </summary>
  1973. private void DeleteRepairImage(string sn)
  1974. {
  1975. //删除文件
  1976. Task.Factory.StartNew(() =>
  1977. {
  1978. string dirPath = Util.CreateSubDir(confMgr.SysConfigParams.SizeRepairImag.SavePath,
  1979. new List<string> { DateTime.Now.ToString("yyyyMMdd"), sn });
  1980. if (!Directory.Exists(dirPath))
  1981. {
  1982. return;
  1983. }
  1984. string[] array = Directory.GetFiles(dirPath);
  1985. foreach (string text in array)
  1986. {
  1987. try
  1988. {
  1989. API.OutputDebugString("清除文件:" + text + "...");
  1990. File.Delete(text);
  1991. }
  1992. catch (Exception ex)
  1993. {
  1994. API.OutputDebugString("Ex1:" + ex.Message);
  1995. }
  1996. }
  1997. dirPath = Util.CreateSubDir(confMgr.SysConfigParams.DefectRepairImag.SavePath,
  1998. new List<string> { DateTime.Now.ToString("yyyyMMdd"), sn });
  1999. if (!Directory.Exists(dirPath))
  2000. {
  2001. return;
  2002. }
  2003. array = Directory.GetFiles(dirPath);
  2004. foreach (string text in array)
  2005. {
  2006. try
  2007. {
  2008. API.OutputDebugString("清除文件:" + text + "...");
  2009. File.Delete(text);
  2010. }
  2011. catch (Exception ex)
  2012. {
  2013. API.OutputDebugString("Ex1:" + ex.Message);
  2014. }
  2015. }
  2016. });
  2017. }
  2018. #endregion
  2019. #region 启动
  2020. /// <summary>
  2021. /// 自动运行
  2022. /// </summary>
  2023. /// <returns></returns>
  2024. public bool StartRun(Form fatherFrm, string detectOrder, int defectCnt, string productCode, string sn)
  2025. {
  2026. bool ret = true;
  2027. //Log("运行", $"启动自动检测流程---料号:{productCode},网版编码:{sn}");
  2028. //运行前清除过期图片文件
  2029. //DateTime st = DateTime.Now;
  2030. DelectPictureFile();
  2031. if(CurrProcessIndex < -1)
  2032. {
  2033. Log("运行", "流程报警中,请清除报警,复位启动", WarningEnum.Low);
  2034. return false;
  2035. }
  2036. if ((statusMgr.Status != SystemStsEnum.Standby)&&(statusMgr.Status != SystemStsEnum.Pause))
  2037. {
  2038. Log("运行", "系统非可运行状态", WarningEnum.Low);
  2039. return false;
  2040. }
  2041. //Log("启动", "移动至上料位...");
  2042. //GotoLoadPos();
  2043. if (!CheckPosIsLoadPos())
  2044. {
  2045. Log("运行", "载具不在上料位!请复位到上料位在启动!", WarningEnum.Low);
  2046. FrmDialog.ShowDialog(fatherFrm, $"载具不在上料位!请复位到上料位在启动!", "警告", false);
  2047. return false;
  2048. }
  2049. if (string.IsNullOrEmpty(productCode))
  2050. {
  2051. Log("运行", "产品料号未选择!", WarningEnum.Low);
  2052. return false;
  2053. }
  2054. string code = productCode;
  2055. //清空显示
  2056. //scannerGBmpQueue.Clear();
  2057. scannerCBmpQueue.Clear();
  2058. scannerGBmpQueue.Clear();
  2059. lstCompareFailZoomImage.Clear();
  2060. contoursAffineTrans1_Out = null;
  2061. //情况流程记录数据
  2062. ProductPT_HeightBaseNum = 0;
  2063. lstHeight.Clear();
  2064. lstHeightBase.Clear();
  2065. lstLineWidth.Clear();
  2066. lstTension.Clear();
  2067. lstPT.Clear();
  2068. lstTestData.Clear();
  2069. //清空打印内容
  2070. CurrPrintInfos.Clear();
  2071. //Log("调试", $"time1:{(DateTime.Now - st).Milliseconds}");
  2072. //st = DateTime.Now;
  2073. int errStep = 0;
  2074. try
  2075. {
  2076. var model = PdtService.GetModelNav(code);
  2077. if (model != null && model.StepInfo != null && model.StepInfo.ProcessList.Count > 0)
  2078. {
  2079. errStep = 1;
  2080. //根据产品设置动态加载外观检测模型文件
  2081. string onnxFile;
  2082. if (!string.IsNullOrWhiteSpace(model.DefectModelFile))
  2083. onnxFile = $"{ConfMgr.Instance.SysConfigParams.AIModelPath}\\{model.DefectModelFile}";
  2084. else
  2085. onnxFile = $"{ConfMgr.Instance.SysConfigParams.AIModelPath}\\default.onnx";
  2086. errStep = 2;
  2087. defectLib.loadModelFile(onnxFile);
  2088. errStep = 3;
  2089. //判断检测工单号
  2090. if (confMgr.SysConfigParams.OpenOredrCheck && string.IsNullOrWhiteSpace(detectOrder))
  2091. {
  2092. if (FrmDialog.ShowDialog(fatherFrm, $"检测工单为空是否继续?", "提示", true) != DialogResult.OK)
  2093. {
  2094. Log("运行", "检测工单号为空!", WarningEnum.Low);
  2095. return false;
  2096. }
  2097. else
  2098. Log("运行", "检测工单号为空测试");
  2099. }
  2100. //判定检测工单数量
  2101. if (confMgr.SysConfigParams.OpenOredrCntCheck)
  2102. {
  2103. var detectOrderList = OrderService.GetListNav(detectOrder);
  2104. if (detectOrderList != null && detectOrderList.Count >= defectCnt)
  2105. {
  2106. if (FrmDialog.ShowDialog(fatherFrm, $"检测工单数量已满 {detectOrderList.Count} 是否继续?", "提示", true) != DialogResult.OK)
  2107. {
  2108. Log("运行", "检测工单数量已满!", WarningEnum.Low);
  2109. return false;
  2110. }
  2111. else
  2112. Log("运行", "检测工单数量已满,继续测试");
  2113. }
  2114. }
  2115. //输入SN
  2116. if (string.IsNullOrWhiteSpace(sn))
  2117. {
  2118. Log("运行", "网版编码为空!", WarningEnum.Low);
  2119. return false;
  2120. }
  2121. Log("运行", $"料号:{code},网版编码:{sn},测试工单:{detectOrder} ");
  2122. //记忆sn
  2123. //Remind(sn);
  2124. //查询SN是否重复
  2125. var findSN = OrderService.GetModelNav(sn);
  2126. errStep = 4;
  2127. if ((findSN != null)&&(findSN.ProductInfo.Code == model.Code))
  2128. {
  2129. Log("运行", $"网版编码:{sn}, 已经存在检测数据!");
  2130. if(FrmDialog.ShowDialog(fatherFrm, $"网版编码:{sn}, 已经存在检测数据!", "提示", true) != DialogResult.OK)
  2131. {
  2132. Log("运行", "网版编码重复测试终止运行!", WarningEnum.Low);
  2133. return false;
  2134. }
  2135. else
  2136. Log("运行", "网版编码重复测试");
  2137. //删除已有sn的修复图片
  2138. DeleteRepairImage(sn);
  2139. }
  2140. //Log("调试", $"time3:{(DateTime.Now - st).Milliseconds}");
  2141. //st = DateTime.Now;
  2142. errStep = 5;
  2143. //图纸重新定义 特定用户名称的情况使用,判断是否有图纸?
  2144. if((confMgr.SysConfigParams.CustomerName == "LP")&&(model.AttachmentList != null))
  2145. {
  2146. string gbxBmpPath = "";
  2147. string bmpPath = "";
  2148. Log("运行", $"{gbxBmpPath} {bmpPath} [图纸解析]:图纸数据解析");
  2149. try
  2150. {
  2151. Models.Attachment attachmentFile = model.AttachmentList.FirstOrDefault(m => m.Type == 0);
  2152. if (attachmentFile != null)
  2153. {
  2154. Yolo5.Yolo_Class yolo = new Yolo5.Yolo_Class();
  2155. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}" + attachmentFile.ExtendName;
  2156. bmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}.bmp";
  2157. yolo.CreatPointFolder(gbxBmpPath, bmpPath);
  2158. }
  2159. else
  2160. Log("运行", $"{gbxBmpPath} {bmpPath} [CreatPointFolder失败]:图纸数据为空", WarningEnum.High);
  2161. }
  2162. catch (Exception ex)
  2163. {
  2164. Log("运行", $"{model.Name} {gbxBmpPath} {bmpPath} [CreatPointFolder失败]:{ex.Message}", WarningEnum.High);
  2165. }
  2166. }
  2167. //判断SN数量是否达到批次上限
  2168. //创建表达式
  2169. if (!string.IsNullOrWhiteSpace(model.BatchId) && model.TargetCount > 0)
  2170. {
  2171. var exp1 = Expressionable.Create<Order>()
  2172. .And(m => m.ProductId == model.Id)
  2173. .And(m => m.BatchId == model.BatchId)
  2174. .And(m => m.SN != sn)
  2175. .ToExpression();//注意 这一句 不能少
  2176. errStep = 6;
  2177. if (OrderService.Count(exp1) >= model.TargetCount)
  2178. {
  2179. Log("运行", $"当前产品本批次检测数已达目标数量,请更换检测批次号!", WarningEnum.Low);
  2180. return false;
  2181. }
  2182. errStep = 7;
  2183. }
  2184. //判断是否清空工单打印的数据
  2185. if(model.EnableOrderPrint)
  2186. {
  2187. CurrDefectOrders = OrderService.GetListNav(detectOrder);
  2188. if (CurrDefectOrders == null || CurrDefectOrders.Count == 0)
  2189. {
  2190. Log("运行", $"当前工单:{detectOrder} 未测试,清空所有工单数据!");
  2191. CurrOrderPrintInfos.Clear();
  2192. CurrDefectIndex = 0;
  2193. }
  2194. else
  2195. {
  2196. CurrDefectIndex = CurrDefectOrders.Count;
  2197. }
  2198. Log("运行", $"当前工单:{detectOrder},第{CurrDefectIndex + 1}块,开始测试!");
  2199. }
  2200. //Log("调试", $"time4:{(DateTime.Now - st).Milliseconds}");
  2201. //st = DateTime.Now;
  2202. //界面显示SN
  2203. model.HeightBaseDec = "";
  2204. CurrProductModel = model;
  2205. Log("运行", $"{model.Name} {model.Spec} [{model.Code}]");
  2206. //新旧流程判断
  2207. if (model.StepInfo.ProcessType != "快速流程")
  2208. {
  2209. IsNewStepProcessVel = false;
  2210. OnAutoRuning(new RunEventArgs(sn, model.StepInfo.ProcessList));
  2211. }
  2212. else
  2213. {
  2214. IsNewStepProcessVel = true;
  2215. OnAutoRuning(new RunEventArgs(sn, model.StepInfo.ProcessList, true));
  2216. }
  2217. forLib.clear();
  2218. ifLib.clear();
  2219. TotalCnt = defectCnt;
  2220. errStep = 8;
  2221. order = new Order();
  2222. order.Qualified = true;//默认合格,中间有一项指标不合格则改为false
  2223. order.ProductId = CurrProductModel.Id;
  2224. order.StepId = (int)CurrProductModel.StepId;
  2225. order.DetectOrder = detectOrder;
  2226. order.OrderCode = productCode;
  2227. order.SN = sn;
  2228. order.BatchId = CurrProductModel.BatchId;
  2229. errStep = 9;
  2230. AllDefectCount = 0;
  2231. SizeNGCnt = 0;
  2232. defectBmpNumResult = defectBmpNum = compBmpNum = compBmpIndex = 0;
  2233. IsCurrHeightBase = false;
  2234. //加载产品需要打印的内容
  2235. if (model.PrintInfoList != null)
  2236. CurrPrintInfos = new List<PrintInfo>(model.PrintInfoList.ToArray()); // copy
  2237. if (model.EnableOrderPrint && model.PrintInfoList != null && CurrOrderPrintInfos.Count == 0)
  2238. {
  2239. Log("运行", $"获取打印工单信息{CurrDefectIndex}!");
  2240. CurrOrderPrintInfos = new List<PrintInfo>(model.PrintInfoList.ToArray()); // copy
  2241. }
  2242. //RunQG(true);
  2243. //新流程判断是否测厚度,是的话开启基准检测
  2244. if (IsNewStepProcessVel)
  2245. {
  2246. bool openHeightBaseTest = false;
  2247. string baseParams = "";
  2248. string processName = "";
  2249. foreach (var item in model.StepInfo.ProcessList)
  2250. {
  2251. if((item.ProcessCode == "Height")&&(!confMgr.SysConfigParams.DisableThickness))
  2252. {
  2253. processName = item.ProcessName;
  2254. baseParams = item.ProcessParams;
  2255. ThicknessProp Param = JsonConvert.DeserializeObject<ThicknessProp>(item.ProcessParams);
  2256. openHeightBaseTest = !Param.Disable;
  2257. break;
  2258. }
  2259. }
  2260. if (openHeightBaseTest)
  2261. {
  2262. if (SizeEnable)
  2263. {
  2264. if (HeightProcessTest(0, processName, baseParams, true) < 0)
  2265. return false;
  2266. }
  2267. }
  2268. }
  2269. //Log("启动", "8");
  2270. IsGetStartSig = false;
  2271. CurrProcessIndex = 0;
  2272. CurrPoinntCount = 0;
  2273. CurrStepResult = 0;
  2274. LedRun();
  2275. stopWatch = new Stopwatch();
  2276. _isRuning = true;
  2277. _isAuto = true;
  2278. statusMgr.GotoAuto();
  2279. SendStatus();
  2280. errStep = 10;
  2281. //Log("调试", $"time5:{(DateTime.Now - st).Milliseconds}");
  2282. //st = DateTime.Now;
  2283. //调试,可删
  2284. //CurrDefectOrders = OrderService.GetListNav(order.DetectOrder);
  2285. //if (model.EnableOrderPrint && (CurrDefectOrders.Count == TotalCnt))
  2286. //{
  2287. // Log("工单打印", $"打印机:{confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.OrderTempPath}");
  2288. // ret = PrintFileOrderData(confMgr.SysConfigParams.ExcelPrinterName,
  2289. // model.OrderTempPath, CurrOrderPrintInfos, model);
  2290. // if (ret)
  2291. // Log("工单打印", $"打印成功!");
  2292. // else
  2293. // Log("工单打印", $"打印失败:打印机={confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.OrderTempPath}, 打印数据={CurrOrderPrintInfos}", WarningEnum.Low);
  2294. //}
  2295. }
  2296. else
  2297. Log("运行", model != null ? $"料号{code}不存在!" : $"产品({model.Name})未配置检测流程!", WarningEnum.Low);
  2298. }
  2299. catch (Exception ex)
  2300. {
  2301. Log("运行", $"程序错误-{errStep}:" + ex.Message + "\n", WarningEnum.High);
  2302. }
  2303. return ret;
  2304. }
  2305. /// <summary>
  2306. /// 暂停重启
  2307. /// </summary>
  2308. /// <returns></returns>
  2309. public bool ReStartRun()
  2310. {
  2311. bool ret = false;
  2312. if (CurrProcessIndex >= 1 )
  2313. {
  2314. Log("启动", $"暂停 -> 继续 当前工序索引:{CurrProcessIndex + 1}");
  2315. LedRun();
  2316. _isRuning = true;
  2317. statusMgr.GotoAuto();
  2318. SendStatus();
  2319. ret = true;
  2320. }
  2321. return ret;
  2322. }
  2323. #endregion
  2324. #region 报警等、按钮IO
  2325. /// <summary>
  2326. /// 三色灯报警状态显示
  2327. /// </summary>
  2328. /// <returns></returns>
  2329. public bool WarningShowLed(bool DisEnableBuzz)
  2330. {
  2331. bool sts = false;
  2332. if (statusMgr.Warning == WarningEnum.Normal)
  2333. {
  2334. if(statusMgr.Status == SystemStsEnum.Auto)
  2335. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), true);
  2336. else
  2337. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  2338. if (statusMgr.Status == SystemStsEnum.Pause)
  2339. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), true);
  2340. else
  2341. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), false);
  2342. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  2343. BuzzCnt = 0;
  2344. //判断黄灯是否需要闪烁,调用200ms一次
  2345. if (Blink)
  2346. {
  2347. if(BlinkCnt < 3)
  2348. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), true);
  2349. else if(BlinkCnt < 6)
  2350. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), false);
  2351. BlinkCnt++;
  2352. if (BlinkCnt == 6)
  2353. BlinkCnt = 0;
  2354. }
  2355. else
  2356. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), false);
  2357. }
  2358. if (statusMgr.Warning == WarningEnum.Low)
  2359. {
  2360. //ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  2361. //ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), true);
  2362. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), true);
  2363. //ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  2364. //sts = true;
  2365. }
  2366. if (statusMgr.Warning == WarningEnum.High)
  2367. {
  2368. sts = true;
  2369. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  2370. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), true);
  2371. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), true);
  2372. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  2373. if (confMgr.SysConfigParams.OpenBuzzer && !DisEnableBuzz)
  2374. {
  2375. if(BuzzCnt < 3)
  2376. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), true);
  2377. else if (BuzzCnt < 6)
  2378. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  2379. BuzzCnt++;
  2380. if (BuzzCnt == 6)
  2381. BuzzCnt = 0;
  2382. }
  2383. }
  2384. return sts;
  2385. }
  2386. /// <summary>
  2387. /// 按钮IO检测
  2388. /// </summary>
  2389. /// <returns></returns>
  2390. public int ButtonIOTrg(bool DisEnableDoorAlm)
  2391. {
  2392. int ret = 0;
  2393. bool sts;
  2394. if(confMgr.SysConfigParams.OpenDoor && !DisEnableDoorAlm)
  2395. {
  2396. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.门磁), GetIOBitIndex((int)DIName.门磁), out sts);
  2397. if ((!sts)&&(statusMgr.Status == SystemStsEnum.Auto))
  2398. {
  2399. Log("暂停", "门磁报警-门打开", WarningEnum.Low );
  2400. statusMgr.GotoPause();
  2401. SendStatus();
  2402. ret = 2;
  2403. }
  2404. }
  2405. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.暂停按钮), GetIOBitIndex((int)DIName.暂停按钮), out sts);
  2406. if (sts)
  2407. {
  2408. Log("暂停", "手动暂停");
  2409. statusMgr.GotoPause();
  2410. SendStatus();
  2411. ret = 2;
  2412. }
  2413. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.复位按钮), GetIOBitIndex((int)DIName.复位按钮), out sts);
  2414. if (sts)
  2415. {
  2416. ret = 3;
  2417. //if (SysMgr.Instance.StatusMgr.Status == SystemStsEnum.Warning)
  2418. //{
  2419. // Log("清除", "手动清除报警");
  2420. // if (SysMgr.Instance.IsAuto)
  2421. // SysMgr.Instance.StatusMgr.GotoPause();
  2422. // else
  2423. // SysMgr.Instance.StatusMgr.GotoNormalStandby();
  2424. //}
  2425. }
  2426. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.启动按钮), GetIOBitIndex((int)DIName.启动按钮), out sts);
  2427. if (sts)
  2428. ret = 1;
  2429. //张力触发按钮
  2430. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.触发张力), GetIOBitIndex((int)DIName.触发张力), out sts);
  2431. if ((sts) && (!IsNewStepProcessVel))
  2432. ret = 4;
  2433. else if ((sts) && (IsNewStepProcessVel))
  2434. {
  2435. ret = 5;
  2436. }
  2437. return ret ;
  2438. }
  2439. #endregion
  2440. #region 手动回原
  2441. /// <summary>
  2442. /// 设备硬件重新加载
  2443. /// </summary>
  2444. public void AllResetAndGoHome()
  2445. {
  2446. try
  2447. {
  2448. Log("复位", "系统硬件重置-关闭");
  2449. if(_isInit)
  2450. lensMotorDev.CloseBoard();
  2451. _isInit = false;
  2452. _isAuto = false;
  2453. _isRuning = false;
  2454. statusMgr.ClearWarning();
  2455. AxisDStop();
  2456. axisDev.CloseBoard();
  2457. ioCardDev.ResetAllDO();
  2458. ioCardDev.CloseBoard();
  2459. lightDev.CloseDev();
  2460. thicknessDev.CloseDev();
  2461. tensionDev.CloseDev();
  2462. //Thread.Sleep(500);
  2463. System.GC.Collect();
  2464. for (int i = 0; i < 30; i++)
  2465. {
  2466. System.Windows.Forms.Application.DoEvents();
  2467. Thread.Sleep(100);
  2468. }
  2469. //System.Windows.Forms.Application.DoEvents();
  2470. //Thread.Sleep(500);
  2471. //System.Windows.Forms.Application.DoEvents();
  2472. //Thread.Sleep(500);
  2473. //System.Windows.Forms.Application.DoEvents();
  2474. lensMotorDev = new PmsMotion();
  2475. camDevFront.CloseCamera();
  2476. camDevFront = new CamDev(SysUseCamFront, confMgr.SysConfigParams.FrontCamName, confMgr.SysConfigParams.FrontCamCfgPath);
  2477. camDevBack.CloseCamera();
  2478. camDevBack = new CamDev(SysUseCamBack, confMgr.SysConfigParams.BackCamName, confMgr.SysConfigParams.BackCamCfgPath);
  2479. Log("复位", "系统硬件重置-初始化");
  2480. Log("复位", "IO板卡初始化");
  2481. if (ioCardDev.InitBoard(MaiMuControl.Device.IOBordType.Advantech) < 0)
  2482. {
  2483. Log("IO板卡初始化失败!", "初始化", WarningEnum.High);
  2484. return;
  2485. }
  2486. if (ioCardDev.OpenBoard(confMgr.SysConfigParams.IODevName, confMgr.SysConfigParams.IOCfgPath) < 0)
  2487. {
  2488. Log("打开IO板卡失败!", "初始化", WarningEnum.High);
  2489. return;
  2490. }
  2491. if (ioCardDev.ResetAllDO() < 0)
  2492. {
  2493. Log("IO Reset失败!", "初始化", WarningEnum.High);
  2494. return;
  2495. }
  2496. statusMgr.GotoInitial();
  2497. SendStatus();
  2498. statusMgr.ClearWarning();
  2499. _isInit = true;
  2500. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.复位按钮黄灯), GetIOBitIndex((int)DOName.复位按钮黄灯), true);
  2501. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), true);
  2502. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  2503. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), false);
  2504. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  2505. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  2506. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), false);
  2507. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  2508. //电机初始化
  2509. Log("复位", "运动控制板卡初始化");
  2510. if (axisDev.InitBoard() < 0)
  2511. {
  2512. Log("运动控制板卡初始化失败!", "初始化", WarningEnum.High);
  2513. return;
  2514. }
  2515. if (axisDev.OpenBoard(0, confMgr.SysConfigParams.MotionCfgPath) < 0)
  2516. {
  2517. Log("打开运动控制板卡失败!", "初始化", WarningEnum.High);
  2518. return;
  2519. }
  2520. if (axisDev.LoadBoardParams(0, boardCfgParams) < 0)
  2521. {
  2522. Log("载入运动控制板卡参数失败1!", "初始化", WarningEnum.High);
  2523. return;
  2524. }
  2525. //光源初始化
  2526. Log("复位", "光源控制器初始化");
  2527. int com_num = int.Parse(confMgr.SysConfigParams.LightCom.Remove(0, 3));
  2528. if (lightDev.InitDev(com_num, confMgr.SysConfigParams.LightComBaud) < 0)
  2529. {
  2530. Log("光源控制器初始化失败!", "初始化", WarningEnum.High);
  2531. return;
  2532. }
  2533. //张力传感器初始化
  2534. Log("复位", "张力传感器初始化");
  2535. if (tensionDev.OpenDevByCom(confMgr.SysConfigParams.TensionCom, confMgr.SysConfigParams.TensionComBaud) < 0)
  2536. {
  2537. Log("张力传感器初始化失败!", "初始化", WarningEnum.High);
  2538. return;
  2539. }
  2540. //InitLog("初始化张力传感器成功!");
  2541. //镜头电机初始化
  2542. Log("复位", "镜头电机初始化");
  2543. lensMotorDev.InitBoard();
  2544. if (lensMotorDev.OpenBoardByCom(confMgr.SysConfigParams.LensMotorCom, confMgr.SysConfigParams.LensMotorComBaud) < 0)
  2545. {
  2546. Log("镜头电机初始化失败!", "初始化", WarningEnum.High);
  2547. return;
  2548. }
  2549. //测厚传感器初始化
  2550. Log("复位", "测厚传感器初始化");
  2551. if (thicknessDev.OpenDevByTcp(confMgr.SysConfigParams.ThicknessIP, confMgr.SysConfigParams.ThicknessPort) < 0)
  2552. {
  2553. Log("测厚传感器初始化失败!", "初始化", WarningEnum.High);
  2554. return;
  2555. }
  2556. //相机初始化
  2557. Log("复位", "前部相机初始化");
  2558. if (!camDevFront.InitCamera())
  2559. {
  2560. Log("前部相机初始化失败!", "初始化", WarningEnum.High);
  2561. return;
  2562. }
  2563. if (!camDevFront.OpenCamera())
  2564. {
  2565. Log("前部相机打开失败!", "初始化", WarningEnum.High);
  2566. return;
  2567. }
  2568. Log("复位", "后部相机初始化");
  2569. if (!camDevBack.InitCamera())
  2570. {
  2571. Log("后部相机初始化失败!", "初始化", WarningEnum.High);
  2572. return;
  2573. }
  2574. if (!camDevBack.OpenCamera())
  2575. {
  2576. Log("后部相机打开失败!", "初始化", WarningEnum.High);
  2577. return;
  2578. }
  2579. Log("复位", "系统硬件重置-回原");
  2580. //镜头电机回原
  2581. lensMotorDev.BackHome(0, new HomeVelocityParams());
  2582. lensMotorDev.CheckHomeDone(0, 3000);
  2583. //移动到 4.5X
  2584. //lensMotorDev.MoveAbsPulse(0, new VelocityCurveParams(), (int)SmallAxCmdPos.倍率4_5X);
  2585. //lensMotorDev.CheckDone(0, 5000);
  2586. //移动Axis前等待厚度传感器收回
  2587. if (thicknessDev.GetValue() < Math.Abs(confMgr.SysConfigParams.ThicknessSafeValue))
  2588. {
  2589. Log("厚度传感器不在安全位置!", "初始化", WarningEnum.High);
  2590. return;
  2591. }
  2592. //多轴回原
  2593. if ((homeParamsZ != null) && (homeParamsX1 != null) && (homeParamsX2 != null) && (homeParamsY != null))
  2594. {
  2595. axisDev.ResetAxisState((int)AxisName.Axis0);
  2596. axisDev.ResetAxisState((int)AxisName.Axis1);
  2597. axisDev.ResetAxisState((int)AxisName.Axis2);
  2598. axisDev.ResetAxisState((int)AxisName.Axis3);
  2599. Log("复位", "Z轴开始回原点...");
  2600. axisDev.BackHome((int)AxisName.Axis3, homeParamsZ);
  2601. Log("复位", "X1轴开始回原点...");
  2602. axisDev.BackHome((int)AxisName.Axis0, homeParamsX1);
  2603. Log("复位", "X2轴开始回原点...");
  2604. axisDev.BackHome((int)AxisName.Axis1, homeParamsX1);
  2605. Log("复位", "Y轴开始回原点...");
  2606. //y轴使用io回原
  2607. AxisYGoHome();
  2608. }
  2609. Thread.Sleep(1000);
  2610. //判断轴是否回原成功
  2611. if (!AxisYGoHomeDone(60))
  2612. {
  2613. AxisAllImmediateStop();
  2614. Log("复位", "Y轴回原失败", WarningEnum.High);
  2615. return;
  2616. }
  2617. if (axisDev.CheckHomeDone((int)AxisName.Axis0, 60) != 0)
  2618. {
  2619. AxisAllImmediateStop();
  2620. Log("复位", "X1轴回原失败", WarningEnum.High);
  2621. return;
  2622. }
  2623. if (axisDev.CheckHomeDone((int)AxisName.Axis1, 60) != 0)
  2624. {
  2625. AxisAllImmediateStop();
  2626. Log("复位", "X2轴回原失败", WarningEnum.High);
  2627. return;
  2628. }
  2629. if (axisDev.CheckHomeDone((int)AxisName.Axis3, 60) != 0)
  2630. {
  2631. AxisAllImmediateStop();
  2632. Log("复位", "Z轴回原失败", WarningEnum.High);
  2633. return;
  2634. }
  2635. Log("复位", "所有轴回原成功!");
  2636. //清空y轴发送命令和反馈位置
  2637. axisDev.SetCommandPos((int)AxisName.Axis2, 0);
  2638. axisDev.SetFeedbackPos((int)AxisName.Axis2, 0);
  2639. //X轴标定启用
  2640. if (confMgr.SysConfigParams.OpenAxisXCalibration)
  2641. {
  2642. OpenAxisXCal();
  2643. }
  2644. Log("复位", "移动到上料...");
  2645. //Thread.Sleep(1000);
  2646. LedReady();
  2647. GotoLoadPos();
  2648. //初始化成功
  2649. _isInit = true;
  2650. statusMgr.GotoNormalStandby();
  2651. SendStatus();
  2652. }
  2653. catch (Exception e)
  2654. {
  2655. _isInit = false;
  2656. Log("复位", $"重置失败:{e.Message}", WarningEnum.High);
  2657. }
  2658. }
  2659. #endregion
  2660. #region 位置获取
  2661. public string GetAxisPos()
  2662. {
  2663. string posStrng = "";
  2664. double pos1 = axisDev.GetFeedbackPos((int)AxisName.Axis0);
  2665. double pos2 = axisDev.GetFeedbackPos((int)AxisName.Axis1);
  2666. double pos3 = axisDev.GetFeedbackPos((int)AxisName.Axis2);
  2667. double pos4 = axisDev.GetFeedbackPos((int)AxisName.Axis3);
  2668. double cmd1 = axisDev.GetCommandPos((int)AxisName.Axis0);
  2669. double cmd2 = axisDev.GetCommandPos((int)AxisName.Axis1);
  2670. double cmd3 = axisDev.GetCommandPos((int)AxisName.Axis2);
  2671. double cmd4 = axisDev.GetCommandPos((int)AxisName.Axis3);
  2672. posStrng = "[命令位:" + (cmd1 / (double)GetMMtoPlus(AxisName.Axis0)).ToString("0.0000") +
  2673. " 反馈位:" + (pos1 / (double)GetMMtoPlus(AxisName.Axis0)).ToString("0.0000") + "]" +
  2674. "[命令位:" + (cmd2 / (double)GetMMtoPlus(AxisName.Axis1)).ToString("0.0000") +
  2675. " 反馈位:" + (pos2 / (double)GetMMtoPlus(AxisName.Axis1)).ToString("0.0000") + "]" +
  2676. "[命令位:" + (cmd3 / (double)GetMMtoPlus(AxisName.Axis2)).ToString("0.0000") +
  2677. " 反馈位:" + (pos3 / (double)GetMMtoPlus(AxisName.Axis2)).ToString("0.0000") + "]" +
  2678. "[命令位:" + (cmd4 / (double)GetMMtoPlus(AxisName.Axis3)).ToString("0.0000") +
  2679. " 反馈位:" + (pos4 / (double)GetMMtoPlus(AxisName.Axis3)).ToString("0.0000") + "]";
  2680. return posStrng;
  2681. }
  2682. #endregion
  2683. #endregion
  2684. #region 主流程
  2685. #region 后台
  2686. /// <summary>
  2687. /// 中断工序运行
  2688. /// </summary>
  2689. /// <returns></returns>
  2690. private bool isBreakProcessRun()
  2691. {
  2692. return statusMgr.Status == SystemStsEnum.Pause || statusMgr.Warning == WarningEnum.High ;
  2693. }
  2694. /// <summary>
  2695. /// 后台运行主线程
  2696. /// </summary>
  2697. private void MainThreadFunction()
  2698. {
  2699. while (true)
  2700. {
  2701. try
  2702. {
  2703. if (_cts.IsCancellationRequested)
  2704. break;
  2705. if (IsRuning)
  2706. {
  2707. //暂停开始
  2708. stopWatch.Start();
  2709. do
  2710. {
  2711. CurrProcessIndex = nextProcess(CurrProductModel, CurrProcessIndex);
  2712. } while (CurrProcessIndex >= 0 && !isBreakProcessRun());
  2713. //暂停中断
  2714. stopWatch.Stop();
  2715. _isRuning = false;
  2716. }
  2717. Thread.Sleep(10);
  2718. }
  2719. catch (Exception e)
  2720. {
  2721. _isRuning = false;
  2722. Log("运行报警", "流程运行出错:" + e.Message + "\n", WarningEnum.High);
  2723. }
  2724. }
  2725. }
  2726. #endregion
  2727. #region 缺陷字典
  2728. /// <summary>
  2729. /// 获取缺陷项阈值
  2730. /// </summary>
  2731. /// <param name="m"></param>
  2732. /// <returns></returns>
  2733. private Dictionary<string, float> getProductAreaThreshol(Product m)
  2734. {
  2735. Dictionary<string, float> dic = new Dictionary<string, float>();
  2736. if (!confMgr.SysConfigParams.OpenAsideDefect)
  2737. {
  2738. foreach (var item in m.QualifiedCriterionList)
  2739. dic.Add(item.DefectCode, (float)(item.Size * 25.4 * 25.4 / m.HoleCount / m.HoleCount));//网目 => mm^2
  2740. }
  2741. else
  2742. {
  2743. foreach (var item in m.QualifiedCriterionList)
  2744. dic.Add(item.DefectCode, (float)(item.Size * 25.4 / m.HoleCount));//网目 => mm^2
  2745. }
  2746. //dic.Add(item.DefectCode, (float)(item.Size * 25.4 * 25.4 / m.HoleCount / m.HoleCount));//网目 => mm^2
  2747. //全缺陷项
  2748. //foreach (var item in Enum.GetValues(typeof(DefectCodeEnum)))
  2749. //{
  2750. // var code = EnumExtension.GetEnumDescription((DefectCodeEnum)item);
  2751. // if (!dic.ContainsKey(code))
  2752. // dic.Add(code, 0);
  2753. //}
  2754. //var lstDefect = ConfMgr.GetArrayList<DefectCodeEnum>();
  2755. foreach (var item in confMgr.DefectItemParamsList)
  2756. {
  2757. string code = item.Code;
  2758. if (!dic.ContainsKey(code))
  2759. dic.Add(code, 0);
  2760. }
  2761. return dic;
  2762. }
  2763. /// <summary>
  2764. /// 获取种类阈值
  2765. /// </summary>
  2766. /// <param name="m"></param>
  2767. /// <returns></returns>
  2768. private string getProductThresholClass(Product m)
  2769. {
  2770. string thresStr = "";
  2771. foreach (var item in confMgr.DefectItemParamsList)
  2772. {
  2773. if ((item.Type.Split(',').Count(p => p == "-1") > 0) ||
  2774. (item.Type.Split(',').Count(p => p == m.DefectModelFile.Replace(".onnx", "")) > 0))
  2775. {
  2776. bool have = false;
  2777. if (m.QualifiedCriterionList != null)
  2778. {
  2779. foreach (var queItem in m.QualifiedCriterionList)
  2780. {
  2781. if (queItem.DefectCode == item.Code)
  2782. {
  2783. have = true;
  2784. if (queItem.Threshold != null || queItem.Threshold > 0)
  2785. thresStr += queItem.Threshold.ToString() + ",";
  2786. else
  2787. thresStr += item.Threshold.ToString() + ",";
  2788. break;
  2789. }
  2790. }
  2791. }
  2792. if (!have)
  2793. {
  2794. thresStr += item.Threshold.ToString() + ",";
  2795. }
  2796. }
  2797. }
  2798. //移除最后的,
  2799. if (thresStr.Length > 0)
  2800. {
  2801. thresStr = thresStr.Remove(thresStr.Length - 1);
  2802. }
  2803. Log("缺陷阈值", $"阈值:{thresStr}");
  2804. return thresStr;
  2805. }
  2806. /// <summary>
  2807. /// 老流程获取种类阈值
  2808. /// </summary>
  2809. /// <param name="m"></param>
  2810. /// <returns></returns>
  2811. private string getProductThresholClass(Product m, string thrStr)
  2812. {
  2813. string thresStr = "";
  2814. string exthresStr = "";
  2815. //获取所有默认值
  2816. foreach (var item in confMgr.DefectItemParamsList)
  2817. {
  2818. if ((item.Type.Split(',').Count(p => p == "-1") > 0) ||
  2819. (item.Type.Split(',').Count(p => p == m.DefectModelFile.Replace(".onnx", "")) > 0))
  2820. {
  2821. thresStr += item.Threshold.ToString() + ",";
  2822. }
  2823. }
  2824. //移除最后的,
  2825. if (thresStr.Length > 0)
  2826. {
  2827. thresStr = thresStr.Remove(thresStr.Length - 1);
  2828. }
  2829. //设置值小于测试项,补上默认值
  2830. if(thrStr.Split(',').Length < thresStr.Split(',').Length)
  2831. {
  2832. exthresStr = thrStr + ",";
  2833. for (int i = thrStr.Split(',').Length; i < thresStr.Split(',').Length; i++)
  2834. {
  2835. exthresStr += thresStr.Split(',')[i] + ",";
  2836. }
  2837. //移除最后的,
  2838. if (exthresStr.Length > 0)
  2839. {
  2840. exthresStr = exthresStr.Remove(exthresStr.Length - 1);
  2841. }
  2842. }
  2843. else if (thrStr.Split(',').Length > thresStr.Split(',').Length)
  2844. {
  2845. exthresStr = "";
  2846. for (int i = 0; i < thresStr.Split(',').Length; i++)
  2847. {
  2848. exthresStr += thrStr.Split(',')[i] + ",";
  2849. }
  2850. //移除最后的,
  2851. if (exthresStr.Length > 0)
  2852. {
  2853. exthresStr = exthresStr.Remove(exthresStr.Length - 1);
  2854. }
  2855. }
  2856. else
  2857. exthresStr = thrStr;
  2858. Log("缺陷阈值", $"阈值:{exthresStr}");
  2859. return exthresStr;
  2860. }
  2861. //统计缺陷类型 [["92.7542","80.85799","99.54083","86.05363","dk","0.52"]]
  2862. public void countDefectClass(List<string>[] list)
  2863. {
  2864. string className;
  2865. if (order.DefectCntInfoList == null)
  2866. order.DefectCntInfoList = new List<DefectCntInfo>();
  2867. for (int i = 0; i < list.Length; i++)
  2868. {
  2869. var fd = confMgr.DefectItemParamsList.Find(p => p.Code == list[i][4]);
  2870. if(fd != null)
  2871. {
  2872. string name = fd.Name;
  2873. //改变list中某个元素值
  2874. var model = order.DefectCntInfoList.Where(c => c.Name == name).FirstOrDefault();
  2875. if(model != null)
  2876. {
  2877. model.DefectCnt++;
  2878. }
  2879. else
  2880. {
  2881. order.DefectCntInfoList.Add(new DefectCntInfo()
  2882. {
  2883. ModifyUserCode = userMgr.LoginUser.Code,
  2884. CreateUserCode = userMgr.LoginUser.Code,
  2885. Code = fd.Code,
  2886. Name = fd.Name,
  2887. DefectCnt = 1,
  2888. });
  2889. }
  2890. }
  2891. className = list[i][4];
  2892. switch (className)
  2893. {
  2894. case "dk":
  2895. order.DKCount++;
  2896. break;
  2897. case "zw":
  2898. order.ZWCount++;
  2899. break;
  2900. case "gsyc":
  2901. order.GSYCCount++;
  2902. break;
  2903. case "xws":
  2904. order.XWSCount++;
  2905. break;
  2906. case "qk":
  2907. order.QKCount++;
  2908. break;
  2909. case "zk":
  2910. order.ZKCount++;
  2911. break;
  2912. case "pp":
  2913. order.PPCount++;
  2914. break;
  2915. case "hs":
  2916. order.HSCount++;
  2917. break;
  2918. case "yx":
  2919. order.YXCount++;
  2920. break;
  2921. case "xb":
  2922. order.XBCount++;
  2923. break;
  2924. case "sx": //sx 变为 gs
  2925. order.SXCount++;
  2926. break;
  2927. //case "ds":
  2928. // order.DSCount++;
  2929. // break;
  2930. //case "gsdl":
  2931. // order.GSDLCount++;
  2932. // break;
  2933. //case "cjdk":
  2934. // order.CJDKCount++;
  2935. // break;
  2936. default:
  2937. //Log($"数据统计", $"错误参数:{className}", WarningEnum.Low);
  2938. break;
  2939. }
  2940. }
  2941. }
  2942. #endregion
  2943. //model.Type=1 系统校正
  2944. /// <summary>
  2945. ///
  2946. /// </summary>
  2947. /// <param name="model"></param>
  2948. /// <param name="stepIndex">0-n</param>
  2949. /// <returns>大于等于0正常工序; -1:结束 -2:异常</returns>
  2950. private int nextProcess(Models.Product model, int stepIndex)
  2951. {
  2952. try
  2953. {
  2954. #region 工序加载
  2955. //记录当前index
  2956. this.CurrProcessIndex = stepIndex;
  2957. OnAutoRuning(new RunEventArgs(stepIndex));
  2958. //判断是否中断或暂停
  2959. if (isBreakProcessRun())
  2960. return stepIndex;
  2961. //开始计时
  2962. if ( model.StepInfo.StartTimeIndex > 0 && model.StepInfo.StartTimeIndex == stepIndex + 1)
  2963. stopWatch.Restart();
  2964. var processtype = model.StepInfo.ProcessType;
  2965. bool IsNewStep = processtype == "快速流程" ? true: false;
  2966. var processList = model.StepInfo.ProcessList;
  2967. var processInfo = processList[stepIndex];
  2968. string processName = processInfo.ProcessName;
  2969. //当前测试点个数
  2970. int TestCnt = 0;
  2971. //AddTextEvent($"{stepIndex + 1}-{processName}", $"工序开始...");
  2972. string jsonParams = null;//配方
  2973. //使用产品配方
  2974. if (model.ProductProcessList != null && model.ProductProcessList.Count > 0)
  2975. {
  2976. ProductProcess productProcessParams = model.ProductProcessList.First(m => m.ProcessCode == processInfo.ProcessCode);
  2977. if (productProcessParams != null)
  2978. {
  2979. jsonParams = productProcessParams.ProcessParams;
  2980. Log($"{stepIndex + 1}-{processName}", $"使用产品专用配方:{jsonParams}");
  2981. }
  2982. }
  2983. //使用流程默认配方
  2984. if (jsonParams == null)
  2985. {
  2986. jsonParams = processInfo.ProcessParams;
  2987. if (jsonParams == null) throw new Exception("配方为null!!");
  2988. if(IsNewStep)
  2989. Log($"{stepIndex + 1}-{processName}", $"使用 快速流程 默认配方:{jsonParams}");
  2990. else
  2991. Log($"{stepIndex + 1}-{processName}", $"使用 高级流程 默认配方:{jsonParams}");
  2992. }
  2993. #endregion
  2994. //加载工序参数
  2995. JObject processParam = JObject.Parse(jsonParams);
  2996. TestCnt = 0;
  2997. bool s_Qualified = true;
  2998. if (!processParam.ContainsKey("Disable") || !processParam.Value<bool>("Disable"))
  2999. {
  3000. if (!IsNewStep)
  3001. {
  3002. #region 老流程/高级流程
  3003. AutoResetEvent endEvent;
  3004. uint sleepPre = processParam.Value<uint>("SleepPre");
  3005. uint sleepLater = processParam.Value<uint>("SleepLater");
  3006. if (sleepPre > 0)
  3007. Thread.Sleep((int)sleepPre);
  3008. double limitThresholdVal, lowerThresholdVal; //Size,Defect
  3009. //======Switch 工序类型
  3010. bool asynRun;
  3011. string gbxBmpPath = "";
  3012. Models.Attachment attachmentFile;
  3013. int liStatocStepIndex = stepIndex;
  3014. switch (processInfo.ProcessCode)
  3015. {
  3016. case "IOCard":
  3017. #region
  3018. var direction = (IODirectionEnum)processParam.Value<int>("Direction");
  3019. if (direction == IODirectionEnum.输入 || direction == IODirectionEnum.输入输出)
  3020. {
  3021. uint IN_Waiting_Timeout = processParam.Value<uint>("IN_Waiting_Timeout");
  3022. Log($"{stepIndex + 1}-{processName}", $"等待I/O输入信号{(IN_Waiting_Timeout > 0 ? $"(超时时长: {IN_Waiting_Timeout})" : "...")}");
  3023. string[] inValue = processParam.Value<JArray>("IN_OP_SHOW").ToObject<List<string>>().ToArray();
  3024. uint inWaitingTime = 0;
  3025. while (true)
  3026. {
  3027. if (isBreakProcessRun())
  3028. return stepIndex;
  3029. byte[] DIData;
  3030. ioCardDev.GetDIByteState(out DIData);
  3031. if (compareIOInput(inValue, DIData))
  3032. break;
  3033. Thread.Sleep(10);
  3034. inWaitingTime += 10;
  3035. if (IN_Waiting_Timeout > 0 && inWaitingTime >= IN_Waiting_Timeout)
  3036. {
  3037. Log($"{stepIndex + 1}-{processName}", $"输入等待超时告警!", WarningEnum.High);
  3038. return stepIndex;
  3039. }
  3040. }
  3041. Log($"{stepIndex + 1}-{processName}", $"I/O输入信号对比完成!");
  3042. }
  3043. if (direction == IODirectionEnum.输出 || direction == IODirectionEnum.输入输出)
  3044. io_output($"{stepIndex + 1}-{processName}", processParam);
  3045. #endregion
  3046. break;
  3047. case "Tension":
  3048. #region
  3049. Log($"{stepIndex + 1}-{processName}", $"忽略不支持流程!");
  3050. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  3051. #endregion
  3052. break;
  3053. case "Height":
  3054. #region
  3055. if (confMgr.SysConfigParams.DisableThickness)
  3056. {
  3057. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  3058. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  3059. break;
  3060. }
  3061. if (!WaitAllAxisDone())//因启用轴异步功能,使用前需等待
  3062. {
  3063. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  3064. return stepIndex;
  3065. }
  3066. limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
  3067. lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
  3068. bool IsRevise = processParam.Value<bool>("IsRevise");
  3069. double relBaseValue = processParam.Value<double>("RelBaseValue"); //配方中相对偏移值
  3070. var heightValue = thicknessDev.GetValue();
  3071. heightValue = Math.Round(heightValue, 2);//保留2位小数
  3072. File.AppendAllText(Directory.GetCurrentDirectory() + "\\厚度测量记录.txt", heightValue + "\r\n");//TEMP
  3073. if (!IsRevise && heightValue < 0)
  3074. {
  3075. Log($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue},异常数据,终止任务!", WarningEnum.High);
  3076. return stepIndex;
  3077. }
  3078. //厚度Base校正
  3079. if (IsRevise)
  3080. {
  3081. var reviseHeight = heightValue + relBaseValue;
  3082. model.HeightBaseDec += reviseHeight + ";";
  3083. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"base值:{reviseHeight} = 厚度值:{heightValue}+偏移值:{relBaseValue}"));
  3084. Log($"{stepIndex + 1}-{processName}", $"base值:{reviseHeight} = 厚度值:{heightValue}+偏移值:{relBaseValue},校正索引队列:{model.HeightBaseDec}");
  3085. }
  3086. else
  3087. {
  3088. Log($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue},base值:{model.HeightBaseDec},偏移值:{relBaseValue},系统偏移值:{confMgr.SysConfigParams.Thickness_Offset},当前base索引:{ProductPT_HeightBaseNum}");
  3089. double heightDev = 0;
  3090. var heightDev_BaseList = model.HeightBaseDec.Split(new char[] { ';', ',' });
  3091. if (heightDev_BaseList.Count() > ProductPT_HeightBaseNum && heightDev_BaseList[ProductPT_HeightBaseNum].Trim() != "")
  3092. heightDev = Convert.ToDouble(heightDev_BaseList[ProductPT_HeightBaseNum].Trim());
  3093. ProductPT_HeightBaseNum++;
  3094. double heightValue2 = Math.Abs(heightDev - heightValue) + relBaseValue + confMgr.SysConfigParams.Thickness_Offset;
  3095. heightValue2 = Math.Round(heightValue2, 2);
  3096. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"厚度值:{heightValue2}"));
  3097. lstHeight.Add(heightValue2);
  3098. Log($"厚度值", $"厚度{lstHeight.Count}:{heightValue2}");
  3099. OnAutoRuning(new RunEventArgs(21, lstHeight, model.HeightBaseValue + model.HeightUpFloatValue, model.HeightBaseValue - model.HeightDownFloatValue));
  3100. double HeightValue = Math.Round(lstHeight.Average(), 2);
  3101. if (order != null)
  3102. order.HeightValue = HeightValue;
  3103. if (order != null)
  3104. {
  3105. if (lstHeight.Count == 1)
  3106. order.Height1 = heightValue2;
  3107. else if (lstHeight.Count == 2)
  3108. order.Height2 = heightValue2;
  3109. else if (lstHeight.Count == 3)
  3110. order.Height3 = heightValue2;
  3111. else if (lstHeight.Count == 4)
  3112. order.Height4 = heightValue2;
  3113. else if (lstHeight.Count == 5)
  3114. order.Height5 = heightValue2;
  3115. }
  3116. double HeightUpper = model.HeightBaseValue + model.HeightUpFloatValue;
  3117. double HeightLower = model.HeightBaseValue - model.HeightDownFloatValue;
  3118. if (HeightUpper + HeightLower > 0 && (HeightValue > HeightUpper || HeightValue < HeightLower))
  3119. order.Qualified = false;
  3120. if (limitThresholdVal > 0 && heightValue2 >= limitThresholdVal)
  3121. {
  3122. Log($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue2},达到上限阀值:{limitThresholdVal},请进行下料...", WarningEnum.High);
  3123. CurrProcessIndex = stepIndex + 1;
  3124. return stepIndex;
  3125. }
  3126. else if (lowerThresholdVal > 0 && heightValue2 < lowerThresholdVal)
  3127. {
  3128. Log($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue2},达到下限阀值:{lowerThresholdVal},请进行下料...", WarningEnum.High);
  3129. CurrProcessIndex = stepIndex + 1;
  3130. return stepIndex;
  3131. }
  3132. Log($"{stepIndex + 1}-{processName}", $"厚度值:{heightValue2} (Base值:{heightDev} - 读取数据:{heightValue} + 偏移值:{relBaseValue})");
  3133. }
  3134. #endregion
  3135. break;
  3136. case "Axis":
  3137. #region 多轴后遗留问题:暂停后再启动不知哪几个轴已执行
  3138. JObject processParamTmp = new JObject();
  3139. //兼容旧版单轴
  3140. if (!processParam.ContainsKey("0") && !processParam.ContainsKey("1") && !processParam.ContainsKey("2") && !processParam.ContainsKey("3"))
  3141. {
  3142. processParam.Add("Enable", true);
  3143. processParamTmp.Add(processParam.Value<int>("AxisIndex").ToString(), processParam);
  3144. processParam = processParamTmp;
  3145. }
  3146. //支持多轴移动
  3147. List<int> axisList = new List<int>();
  3148. foreach (var processParamSub in processParam.Properties())
  3149. {
  3150. processParam = processParamSub.Value as JObject;
  3151. Log($"{stepIndex + 1}-{processName}", processParam.ToString());
  3152. if (!processParam.ContainsKey("Disable") || !processParam.Value<bool>("Disable"))
  3153. {
  3154. //asynRun = processParam.Value<bool>("AsynRun");//异步
  3155. int AxisIndex = processParam.Value<int>("AxisIndex");
  3156. axisList.Add(AxisIndex);
  3157. int DeviceType = processParam.Value<int>("DeviceType");
  3158. double VelLow = processParam.Value<double>("VelLow");
  3159. double VelHigh = processParam.Value<double>("VelHigh");
  3160. double Acc = processParam.Value<double>("Acc");
  3161. double Dec = processParam.Value<double>("Dec");
  3162. AxMoveMode MoveMode = (AxMoveMode)processParam.Value<int>("MoveMode");//绝对位置
  3163. double PPUValue = processParam.Value<double>("Value");
  3164. Log($"{stepIndex + 1}-{processName}",
  3165. $"轴{AxisIndex}准备({(MoveMode == AxMoveMode.绝对位置 ? "绝对" : "相对")})运动至{PPUValue}...");
  3166. if (axisDev.CheckDone(AxisIndex, 60) != 0)
  3167. {
  3168. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}到位失败!", WarningEnum.High);
  3169. return stepIndex;
  3170. }
  3171. VelocityCurveParams vel = new VelocityCurveParams(Acc, Dec, VelLow, VelHigh, MotionST, GetMMtoPlus((AxisName)AxisIndex));
  3172. int iret = 0;
  3173. if (MoveMode == AxMoveMode.绝对位置)
  3174. iret = axisDev.MoveAbsValue(AxisIndex, vel, PPUValue);
  3175. else
  3176. iret = axisDev.MoveRelValue(AxisIndex, vel, PPUValue);
  3177. if (iret != 0)
  3178. {
  3179. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}运动失败!", WarningEnum.High);
  3180. return stepIndex;
  3181. }
  3182. }
  3183. }
  3184. //多轴同时运行后强制等待各轴完成
  3185. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  3186. if (!WaitAxisDone(axisList))
  3187. {
  3188. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  3189. return stepIndex;
  3190. }
  3191. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  3192. #endregion
  3193. break;
  3194. case "AxisTag":
  3195. #region
  3196. //asynRun = processParam.Value<bool>("AsynRun");//异步
  3197. string axisSizeTag = processParam.Value<string>("SizeTag");
  3198. int useIndex = processParam.Value<int>("UseIndex");//消费posePT中的索引
  3199. AxMoveMode TagMoveMode = (AxMoveMode)processParam.Value<int>("MoveMode");//绝对位置
  3200. var AxisIndexList = processParam.Value<JArray>("AxisIndexList").ToObject<List<int>>();
  3201. double TagVelLow = processParam.Value<double>("VelLow");
  3202. double TagVelHigh = processParam.Value<double>("VelHigh");
  3203. double TagAcc = processParam.Value<double>("Acc");
  3204. double TagDec = processParam.Value<double>("Dec");
  3205. //判断有无tag
  3206. if (order.SizeTagDataList == null)
  3207. {
  3208. Log($"{stepIndex + 1}-{processName}", $"数据提供者Tag为空!", WarningEnum.High);
  3209. return stepIndex;
  3210. }
  3211. var sizeTagObj = order.SizeTagDataList.LastOrDefault(m => m.SizeTag == axisSizeTag);//用最新的last
  3212. if (sizeTagObj == null)
  3213. {
  3214. Log($"{stepIndex + 1}-{processName}", $"偏移校正轴工序找不到数据提供者Tag:{axisSizeTag}!", WarningEnum.High);
  3215. return stepIndex;
  3216. }
  3217. string[] posePT = sizeTagObj.posePT.Split(',');
  3218. if (posePT.Length < useIndex + AxisIndexList.Count)
  3219. {
  3220. Log($"{stepIndex + 1}-{processName}",
  3221. $"Tag:{axisSizeTag}对应消费索引:{useIndex},Axis数量:{AxisIndexList.Count} 超出postPT:{sizeTagObj.posePT} 范围!", WarningEnum.High);
  3222. return stepIndex;
  3223. }
  3224. double[] TagPPUValue = new double[AxisIndexList.Count];
  3225. for (int i = 0; i < AxisIndexList.Count; i++)
  3226. TagPPUValue[i] = double.Parse(posePT[useIndex + i]);
  3227. string axisTagMsg = $"消费Tag:{axisSizeTag},索引:{useIndex}, 轴:{string.Join(",", AxisIndexList.ToList())},数据:{(TagMoveMode == AxMoveMode.绝对位置 ? "绝对" : "相对")}({string.Join(",", TagPPUValue.ToList())})";
  3228. Log($"{stepIndex + 1}-{processName}", axisTagMsg);
  3229. //界面显示
  3230. OnAutoRuning(new RunEventArgs(liStatocStepIndex, axisTagMsg));
  3231. for (int i = 0; i < AxisIndexList.Count && i < TagPPUValue.Length; i++)
  3232. {
  3233. if (axisDev.CheckDone(AxisIndexList[i], 60) != 0)
  3234. {
  3235. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}到位失败!", WarningEnum.High);
  3236. return stepIndex;
  3237. }
  3238. VelocityCurveParams vel = new VelocityCurveParams(TagAcc, TagDec, TagVelLow, TagVelHigh, MotionST, GetMMtoPlus((AxisName)AxisIndexList[i]));
  3239. int iret = 0;
  3240. if (TagMoveMode == AxMoveMode.绝对位置)
  3241. iret = axisDev.MoveAbsValue(AxisIndexList[i], vel, TagPPUValue[i]);
  3242. else
  3243. iret = axisDev.MoveRelValue(AxisIndexList[i], vel, TagPPUValue[i]);
  3244. if (iret != 0)
  3245. {
  3246. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}运动失败!", WarningEnum.High);
  3247. return stepIndex;
  3248. }
  3249. }
  3250. if (sizeTagObj.ConsumeStepIndex == null) sizeTagObj.ConsumeStepIndex = "";
  3251. sizeTagObj.ConsumeStepIndex += $"{stepIndex + 1}-{useIndex}, ";//消费工序ID
  3252. //多轴同时运行后强制等待各轴完成
  3253. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  3254. if (!WaitAxisDone(AxisIndexList))
  3255. {
  3256. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  3257. return stepIndex;
  3258. }
  3259. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  3260. #endregion
  3261. break;
  3262. case "Light":
  3263. #region
  3264. if (confMgr.SysConfigParams.DisableLight)
  3265. {
  3266. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  3267. //界面显示
  3268. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  3269. break;
  3270. }
  3271. int ChannelIndex = processParam.Value<int>("ChannelIndex"); //通道
  3272. int DigitalValue = processParam.Value<int>("DigitalValue"); //亮度
  3273. int nowDiaitalValue = lightDev.GetLightDigitalValue(ChannelIndex);
  3274. Log($"{stepIndex + 1}-{processName}", $"通道{ChannelIndex}当前值:{nowDiaitalValue},准备更新值:{DigitalValue}...");
  3275. lightDev.SetLightDigitalValue(ChannelIndex, DigitalValue);
  3276. nowDiaitalValue = lightDev.GetLightDigitalValue(ChannelIndex);
  3277. Log($"{stepIndex + 1}-{processName}", $"通道{ChannelIndex}更新后当前值:{nowDiaitalValue}。");
  3278. #endregion
  3279. break;
  3280. case "Scanner_GENTL":
  3281. #region
  3282. if (confMgr.SysConfigParams.DisableBackCam)
  3283. {
  3284. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  3285. //界面显示
  3286. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  3287. break;
  3288. }
  3289. AIEngineLibEnum AIEngineLib = AIEngineLibEnum.缺陷库;
  3290. if (processParam.ContainsKey("AIEngineLib"))
  3291. AIEngineLib = (AIEngineLibEnum)processParam.Value<int>("AIEngineLib");
  3292. float ExposureTime = processParam.Value<float>("ExposureTime"); //曝光
  3293. float Gain = processParam.Value<float>("Gain"); //增益
  3294. float ResultingFrameRate = processParam.Value<float>("ResultingFrameRate"); //帧率
  3295. Log($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  3296. CamDevBack.SetExposure(ExposureTime);
  3297. CamDevBack.SetGain(Gain);
  3298. CamDevBack.SetResultingFrameRate(ResultingFrameRate);
  3299. for (int snapi = 0; snapi < snapCnt; snapi++)
  3300. {
  3301. DateTime dt = DateTime.Now;
  3302. CamDevBack.ClearImageQueue();
  3303. Acquisition acq = CamDevBack.Snap(1, 5000);
  3304. if (acq.GrabStatus != "GrabPass")
  3305. {
  3306. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片失败{snapi}!", WarningEnum.High);
  3307. if(snapi < snapCnt -1)
  3308. {
  3309. Thread.Sleep(100);
  3310. continue;
  3311. }
  3312. else
  3313. return stepIndex;
  3314. }
  3315. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片完成{snapi}[" + (DateTime.Now - dt).Milliseconds.ToString() + "ms]");
  3316. //显示
  3317. OnAutoRuning(new RunEventArgs(1, acq.Image));
  3318. //----缺陷队列
  3319. if (AIEngineLib == AIEngineLibEnum.缺陷库 || AIEngineLib == AIEngineLibEnum.缺陷与测量库)
  3320. {
  3321. var mat = CamDev.HImageToMat(acq.Image);
  3322. scannerGBmpQueue.Enqueue(new scannerGBmpLoc(mat,
  3323. GetAxisPosValueMM((int)AxisName.Axis1),
  3324. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  3325. Log($"{stepIndex + 1}-{processName}", $"缺陷图像队列数量: {scannerGBmpQueue.Count}");
  3326. }
  3327. if (AIEngineLib == AIEngineLibEnum.测量库 || AIEngineLib == AIEngineLibEnum.缺陷与测量库)
  3328. {
  3329. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  3330. acq.Image.Clone(),
  3331. GetAxisPosValueMM((int)AxisName.Axis1),
  3332. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  3333. Log($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列," +
  3334. $"X:{GetAxisPosValueMM((int)AxisName.Axis1)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  3335. $"数量: {scannerCBmpQueue.Count}");
  3336. }
  3337. break;
  3338. }
  3339. #endregion
  3340. break;
  3341. case "Scanner_CC":
  3342. #region
  3343. if (confMgr.SysConfigParams.DisableFrontCam)
  3344. {
  3345. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  3346. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  3347. break;
  3348. }
  3349. if (!WaitAllAxisDone())//因启用轴异步功能,使用前需等待
  3350. {
  3351. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  3352. return stepIndex;
  3353. }
  3354. float ExposureTimeCC = processParam.Value<float>("ExposureTime"); //曝光
  3355. float GainCC = processParam.Value<float>("Gain"); //增益
  3356. float ResultingFrameRateCC = processParam.Value<float>("ResultingFrameRate"); //帧率
  3357. CamDevFront.SetExposure(ExposureTimeCC);
  3358. CamDevFront.SetGain(GainCC);
  3359. CamDevFront.SetResultingFrameRate(ResultingFrameRateCC);
  3360. Log($"{stepIndex + 1}-{processName}", $"相机参数设置完成。");
  3361. bool tAutoFocus = true;
  3362. double tFocusStep = 0.02;
  3363. double tDirStep = 0.04;
  3364. int tWaitTime = 200;
  3365. int tTimeOut = 30000;
  3366. try
  3367. {
  3368. tAutoFocus = processParam.Value<bool>("AutoFocus");
  3369. tFocusStep = processParam.Value<double>("FocusStep");
  3370. tDirStep = processParam.Value<double>("DirStep");
  3371. tWaitTime = processParam.Value<int>("WaitTime");
  3372. tTimeOut = processParam.Value<int>("TimeOut");
  3373. if((tAutoFocus == false)&&(tFocusStep == 0) && (tDirStep == 0) && (tWaitTime == 0) && (tTimeOut == 0))
  3374. {
  3375. tAutoFocus = false;
  3376. tFocusStep = 0.02;
  3377. tDirStep = 0.04;
  3378. tWaitTime = 200;
  3379. tTimeOut = 30000;
  3380. Log($"{stepIndex + 1}-{processName}", $"无参数,使用默认参数!");
  3381. }
  3382. }
  3383. catch
  3384. {
  3385. tAutoFocus = false;
  3386. tFocusStep = 0.02;
  3387. tDirStep = 0.04;
  3388. tWaitTime = 200;
  3389. tTimeOut = 30000;
  3390. Log($"{stepIndex + 1}-{processName}", $"错误参数,使用默认参数!");
  3391. }
  3392. if ((tAutoFocus)&&(ExposureTimeCC > 0))
  3393. {
  3394. Log($"{stepIndex + 1}-{processName}", $"开始自动聚焦...");
  3395. if (!AutoFocus(tFocusStep, tDirStep, tWaitTime, tTimeOut))
  3396. {
  3397. Log($"{stepIndex + 1}-{processName}", $"自动聚焦失败!", WarningEnum.High);
  3398. return stepIndex;
  3399. }
  3400. Log($"{stepIndex + 1}-{processName}", $"自动聚焦完成");
  3401. }
  3402. Log($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  3403. for (int i = 0; i < snapCnt; i++)
  3404. {
  3405. DateTime dt0 = DateTime.Now;
  3406. CamDevFront.ClearImageQueue();
  3407. Acquisition acq0 = CamDevFront.Snap(1, 5000);
  3408. if (acq0.GrabStatus != "GrabPass")
  3409. {
  3410. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片失败{i}!", WarningEnum.High);
  3411. //return stepIndex;
  3412. if (i < snapCnt - 1)
  3413. {
  3414. Thread.Sleep(100);
  3415. continue;
  3416. }
  3417. else
  3418. return stepIndex;
  3419. }
  3420. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片完成{i}[" + (DateTime.Now - dt0).Milliseconds.ToString() + "ms]");
  3421. //显示
  3422. OnAutoRuning(new RunEventArgs(0, acq0.Image));
  3423. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  3424. acq0.Image.Clone(),
  3425. GetAxisPosValueMM((int)AxisName.Axis0),
  3426. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  3427. Log($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列," +
  3428. $"X:{GetAxisPosValueMM((int)AxisName.Axis0)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  3429. $"数量: {scannerCBmpQueue.Count}");
  3430. break;
  3431. }
  3432. #endregion
  3433. break;
  3434. case "SmallAxis":
  3435. #region
  3436. if (confMgr.SysConfigParams.DisableLensMotor)
  3437. {
  3438. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  3439. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  3440. break;
  3441. }
  3442. int CmdPos = processParam.Value<int>("CmdPos"); //命令脉冲
  3443. Log($"{stepIndex + 1}-{processName}", $"开始由起始位置{lensMotorDev.GetFeedbackPos(0)}运动到{CmdPos}...");
  3444. lensMotorDev.MoveAbsPulse(0, new VelocityCurveParams(), CmdPos);
  3445. lensMotorDev.CheckDone(0, 10000);
  3446. Log($"{stepIndex + 1}-{processName}", $"运动完成,当前位置:{lensMotorDev.GetFeedbackPos(0)}");
  3447. #endregion
  3448. break;
  3449. case "Size":
  3450. #region
  3451. asynRun = processParam.Value<bool>("AsynRun");//异步
  3452. limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
  3453. lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
  3454. int sizeIndex = processParam.Value<int>("Index");
  3455. string sizeTag = processParam.ContainsKey("SizeTag") ? processParam.Value<string>("SizeTag") : "";
  3456. List<string> testLabels = new List<string>();
  3457. foreach (var item in confMgr.SizeItemParamsList)
  3458. {
  3459. //名称可以直接获取
  3460. testLabels.Add(item.Name);
  3461. }
  3462. List<double> posList = new List<double>();
  3463. double[] posArray = null;
  3464. //string[] pointType = new string[17] { "Y轴方向PT值检测" , "线宽正面" , "反面检测" ,
  3465. //"X轴方向PT值检测","主栅连接线检测","主栅宽度检测","主栅间距","细栅间距检测","背极宽度",
  3466. //"主栅长度检测","Mark点横向间距","Mark点竖向间距","鱼叉口长","鱼叉口宽","鱼叉口间距",
  3467. //"蜈蚣角长", "蜈蚣角宽"};
  3468. string[] pointType = testLabels.ToArray();
  3469. int[] adaqter = new int[pointType.Length];
  3470. if (true)
  3471. {
  3472. for (int i = 0; i < pointType.Length; i++)
  3473. {
  3474. List<TestDefectPoints> t1 = model.TestDefectPointsList.Where(q => q.PointCode == pointType[i]).ToList();
  3475. if (t1.Count > 0)
  3476. {
  3477. if (pointType[i] == "Y轴方向PT值检测" || pointType[i] == "X轴方向PT值检测")
  3478. adaqter[i] = t1.Count;
  3479. else
  3480. adaqter[i] = t1.Count * 2;
  3481. //添加点位
  3482. for (int j = 0; j < t1.Count; j++)
  3483. {
  3484. if (t1[j].PointCode == "Y轴方向PT值检测")
  3485. posList.Add(t1[j].X);
  3486. else if (t1[j].PointCode == "X轴方向PT值检测")
  3487. posList.Add(t1[j].Y);
  3488. else
  3489. {
  3490. posList.Add(t1[j].X);
  3491. posList.Add(t1[j].Y);
  3492. }
  3493. }
  3494. }
  3495. }
  3496. }
  3497. else
  3498. {
  3499. ;
  3500. }
  3501. CurrAdaqter = adaqter;
  3502. if (posList.Count > 0)
  3503. { posArray = posList.ToArray(); }
  3504. bool useMap = false;
  3505. double[] getPosArray = null;
  3506. if (model.TestDefectPointsList != null && model.TestDefectPointsList.Count > 0)
  3507. {
  3508. ;
  3509. }
  3510. else
  3511. {
  3512. //2023-10-27
  3513. List<double> getPosList = new List<double>();
  3514. try
  3515. {
  3516. //是否有新的使用点位
  3517. useMap = processParam.Value<bool>("UseMapPoints");
  3518. if (useMap)
  3519. {
  3520. var list = model.GetPointList.Split(',');
  3521. List<double> dList = new List<double>();
  3522. if (list.Length < 28)
  3523. {
  3524. for (int i = 0; i < 28; i++)
  3525. dList.Add(0);
  3526. }
  3527. else
  3528. {
  3529. for (int i = 0; i < list.Length; i++)
  3530. dList.Add(double.Parse(list[i]));
  3531. }
  3532. getPosList = dList;
  3533. }
  3534. else
  3535. {
  3536. for (int i = 0; i < 28; i++)
  3537. getPosList.Add(0);
  3538. }
  3539. //getPosList = processParam.Value<JArray>("GetPointList").ToObject<List<double>>();
  3540. }
  3541. catch
  3542. {
  3543. for (int i = 0; i < 28; i++)
  3544. getPosList.Add(0);
  3545. }
  3546. getPosArray = getPosList.ToArray();
  3547. adaqter = new int[ConfMgr.Instance.SizeItemParamsList.Count];
  3548. adaqter[0] = 5;
  3549. adaqter[1] = 18;
  3550. //adaqter = new int[23] { 5, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  3551. }
  3552. if (scannerCBmpQueue.Count < 1)
  3553. {
  3554. Log($"{stepIndex + 1}-{processName}", $"尺寸检测异常,无源图像!!", WarningEnum.Low);
  3555. return stepIndex;
  3556. }
  3557. var bmpCBmpQueue = scannerCBmpQueue.Dequeue();
  3558. Log($"{stepIndex + 1}-{processName}", $"开始尺寸检测,index:{sizeIndex},posX:{bmpCBmpQueue.PosX},posY:{bmpCBmpQueue.PosY},图像队列数量: {scannerCBmpQueue.Count}...");
  3559. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  3560. Log($"{stepIndex + 1}-{processName}", $"尺寸检测,index:{sizeIndex},{model.AttachmentList.Count}|{(attachmentFile == null ? "null" : attachmentFile.NameTimestamp + attachmentFile.ExtendName)}");
  3561. if (attachmentFile != null)
  3562. {
  3563. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  3564. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName))
  3565. gbxBmpPath = "";
  3566. }
  3567. if ((sizeIndex == 333 || sizeIndex == 777) && gbxBmpPath == "")
  3568. Log($"{stepIndex + 1}-{processName}", $"尺寸检测,index:{sizeIndex},图纸不存在!", WarningEnum.Low);
  3569. //2023-10-27
  3570. if (useMap && (sizeIndex == 3333) && (getPosArray != null) && (getPosArray.Count() == 28) && (getPosArray[0] != 0))
  3571. Log($"{stepIndex + 1}-{processName}", $"开始图纸读点,index:{sizeIndex},PT1:{getPosArray[0]},PT2:{getPosArray[2]},PT3:{getPosArray[4]},PT4:{getPosArray[6]},PT5:{getPosArray[8]}," +
  3572. $"线宽1:[{getPosArray[10]},{getPosArray[11]}],线宽2:[{getPosArray[12]},{getPosArray[13]}],线宽3:[{getPosArray[14]},{getPosArray[15]}]," +
  3573. $"线宽4:[{getPosArray[16]},{getPosArray[17]}],线宽5:[{getPosArray[18]},{getPosArray[19]}],线宽6:[{getPosArray[20]},{getPosArray[21]}]," +
  3574. $"线宽7:[{getPosArray[22]},{getPosArray[23]}],线宽8:[{getPosArray[24]},{getPosArray[25]}],线宽9:[{getPosArray[26]},{getPosArray[27]}]");
  3575. else
  3576. Log($"{stepIndex + 1}-{processName}", $"AdapterPos:" + $",{JsonConvert.SerializeObject(posArray)},Adapter:{JsonConvert.SerializeObject(adaqter)}");
  3577. //需要偏移校正,index=0时不能异步 //10,20,30... 
  3578. endEvent = new AutoResetEvent(false);
  3579. SizeLib.add(new SizeTask()
  3580. {
  3581. stepIndex = stepIndex,
  3582. processName = processName,
  3583. sizeTag = sizeTag,
  3584. engineName = processParam.Value<string>("EngineName"),
  3585. Himage = bmpCBmpQueue.Himage.Clone(),//bmp/file_path二选一,优先bmp
  3586. file_path = bmpCBmpQueue.Path,
  3587. drawingPagePath = gbxBmpPath,
  3588. posX = bmpCBmpQueue.PosX,
  3589. posY = bmpCBmpQueue.PosY,
  3590. //2023-10-27
  3591. AdapterPos = posArray,
  3592. Adapter = adaqter,
  3593. PTandLinePos = getPosArray,
  3594. index = sizeIndex,// scannerCBmpIndex++,
  3595. ContoursAffineTrans1_Out = this.contoursAffineTrans1_Out,//只有777时才使用最近333输出的结果
  3596. finishEvent = (res) =>
  3597. {
  3598. try
  3599. {
  3600. //比对
  3601. if (res.index == 777)//比对
  3602. {
  3603. if (res.isSucceed)
  3604. {
  3605. //界面显示
  3606. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},图像比对:{(res.CompResult ? "通过" : "未通过")} "));
  3607. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对,index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},结果:{(res.CompResult ? "通过" : "未通过")}");
  3608. //
  3609. if (order.CompareResult < 2)
  3610. order.CompareResult = res.CompResult ? 1 : 2;
  3611. if (!res.CompResult)
  3612. {
  3613. //不合格
  3614. order.Qualified = false;
  3615. }
  3616. //更新比对看板 对比置零3
  3617. if (!res.CompResult)
  3618. SizeNGCnt++;
  3619. if (SizeNGCnt > 0)
  3620. OnAutoRuning(new RunEventArgs(3, false, SizeNGCnt));
  3621. else
  3622. OnAutoRuning(new RunEventArgs(3, true, SizeNGCnt));
  3623. if (!res.CompResult)
  3624. {
  3625. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对,未通过结果:{JsonConvert.SerializeObject(res.defectInfor2RestorationDesk)}");
  3626. //转为图纸上坐标位置
  3627. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  3628. {
  3629. //AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"转换到图纸后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
  3630. if (order.DefectInfoList == null)
  3631. order.DefectInfoList = new List<DefectInfo>();
  3632. foreach (var item in res.defectInfor2RestorationDeskPage)
  3633. order.DefectInfoList.Add(new DefectInfo()
  3634. {
  3635. Type = 1,
  3636. Code = item[3],
  3637. X = double.Parse(item[1]),
  3638. Y = double.Parse(item[2]),
  3639. ZXD = double.Parse(item[4]),
  3640. Index = int.Parse(item[0]),
  3641. ModifyUserCode = userMgr.LoginUser.Code,
  3642. CreateUserCode = userMgr.LoginUser.Code,
  3643. });
  3644. }
  3645. //比对失败的图片 -- 用于修复台调用
  3646. Bitmap bmpCompareFailZoomImage = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.Zoom_Image_mat);
  3647. lstCompareFailZoomImage.Add(bmpCompareFailZoomImage);
  3648. if (confMgr.SysConfigParams.SizeRepairImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeRepairImag.SavePath))
  3649. {
  3650. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeRepairImag.SavePath,
  3651. new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3652. //path += $"Size_SN{order.SN}_I{res.index}_X{res.Defects_X}_Y{res.Defects_Y}_C0_{ model.StepInfo.Name}";
  3653. path += $"Size_SN{order.SN}_I{compBmpIndex}_X{res.posX}_Y{res.posY}_C0_{model.StepInfo.Name}";
  3654. lock (ImageSaveObj)
  3655. {
  3656. bmpCompareFailZoomImage.Save(path + ".bmp", ImageFormat.Bmp);
  3657. if (res.defectInfor2RestorationDesk != null && res.defectInfor2RestorationDesk.Count > 0)
  3658. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
  3659. }
  3660. }
  3661. //保存不良原图
  3662. if (confMgr.SysConfigParams.SizeNGImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeNGImag.SavePath))
  3663. {
  3664. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeNGImag.SavePath,
  3665. new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3666. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}.bmp";
  3667. Log($"{res.stepIndex + 1}-{processName}", $"未通过图片保存:{path}");
  3668. if (res.Himage != null)
  3669. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  3670. else
  3671. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  3672. }
  3673. }
  3674. }
  3675. else
  3676. {
  3677. order.CompareResult = 2;
  3678. order.Qualified = false;
  3679. SizeNGCnt++;
  3680. OnAutoRuning(new RunEventArgs(3, false, SizeNGCnt));
  3681. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index},图像比对失败!"));
  3682. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对失败,index:{res.index}-{compBmpIndex}.", WarningEnum.Low);
  3683. }
  3684. compBmpIndex++;
  3685. }
  3686. //MARK
  3687. else if (res.index == 111 || res.index == 222 || res.index == 333 || res.index == 444)
  3688. {
  3689. Log($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index},结果记录...");
  3690. if (res.index == 333) this.contoursAffineTrans1_Out = res.ContoursAffineTrans1_Out;//不管成功失败都替换
  3691. if (res.isSucceed)
  3692. {
  3693. Thread.Sleep(100);
  3694. Log($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index}; 当前值:{string.Join(",", res.MarkPointList)}");
  3695. JArray markDatas;
  3696. if (string.IsNullOrWhiteSpace(order.MarkData))
  3697. markDatas = new JArray() { 0, 0, 0, 0, 0, 0, 0, 0 };
  3698. else
  3699. markDatas = JArray.Parse(order.MarkData);
  3700. for (int i = 0; i < res.MarkPointList.Count(); i++)
  3701. if (res.MarkPointList[i] != 0)
  3702. markDatas[i] = res.MarkPointList[i];
  3703. order.MarkData = markDatas.ToString();
  3704. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index},Mark点:{order.MarkData} "));
  3705. Log($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index};合并后:{order.MarkData}");
  3706. }
  3707. else
  3708. {
  3709. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index},Mark点计算失败!"));
  3710. Log($"{res.stepIndex + 1}-{processName}", $"Mark点计算失败,index:{res.index}.", confMgr.SysConfigParams.OpenMarkErrorStop ? WarningEnum.High : WarningEnum.Normal);
  3711. }
  3712. //保存
  3713. if (confMgr.SysConfigParams.SizeBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeBigImag.SavePath))
  3714. {
  3715. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3716. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}.bmp";
  3717. if (res.Himage != null)
  3718. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  3719. else
  3720. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  3721. }
  3722. }
  3723. else
  3724. {
  3725. int roundIndex = res.index % 10;
  3726. if (res.isSucceed)
  3727. {
  3728. string tagOutData = "";
  3729. if (res.index == 3333 && !string.IsNullOrWhiteSpace(res.sizeTag))
  3730. {
  3731. tagOutData = $"Tag:{res.sizeTag},posePT:[{string.Join(",", res.posePT)}]";
  3732. if (res.posePT.Length < 2 || res.posePT.Length % 2 != 0)
  3733. {
  3734. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测输出Tag对应posePT非法: {tagOutData}", WarningEnum.High);
  3735. return;
  3736. }
  3737. //2023-10-27
  3738. Log($"{res.stepIndex + 1}-{res.processName}", $"Tag对应posePT: {tagOutData}", WarningEnum.Normal);
  3739. if (order.SizeTagDataList == null)
  3740. order.SizeTagDataList = new List<SizeTagData>();
  3741. order.SizeTagDataList.Add(new SizeTagData()
  3742. {
  3743. SizeTag = res.sizeTag,
  3744. CreateStepIndex = res.stepIndex + 1,
  3745. posePT = string.Join(",", res.posePT)// 回转 Array.ConvertAll(sNums , double.Parse);
  3746. });
  3747. }
  3748. OnAutoRuning(new RunEventArgs(liStatocStepIndex,
  3749. $"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}"));
  3750. Log($"{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} ");
  3751. //测量
  3752. //------TEST
  3753. if (res.index > 20 && res.index < 30)
  3754. {
  3755. //PT测量
  3756. lock (lstPT)
  3757. {
  3758. lstPT.Add(Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4));
  3759. Log($"PT值", $"PT{lstPT.Count}:{Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4)}");
  3760. OnAutoRuning(new RunEventArgs(22, lstPT, model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue));
  3761. double PtValue = Math.Round(lstPT.Average(), 4);
  3762. if (order != null)
  3763. order.PTValue = PtValue;
  3764. if (order != null)
  3765. {
  3766. if (lstPT.Count == 1)
  3767. order.PT1 = Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4);
  3768. else if (lstPT.Count == 2)
  3769. order.PT2 = Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4);
  3770. else if (lstPT.Count == 3)
  3771. order.PT3 = Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4);
  3772. else if (lstPT.Count == 4)
  3773. order.PT5 = Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4);
  3774. else if (lstPT.Count == 5)
  3775. order.PT6 = Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4);
  3776. }
  3777. double PtUpper = model.PTBaseValue + model.PTUpFloatValue;
  3778. double PtLower = model.PTBaseValue - model.PTDownFloatValue;
  3779. if (PtUpper + PtLower > 0 && (PtValue > PtUpper || PtValue < PtLower))
  3780. order.Qualified = false;
  3781. }
  3782. }
  3783. //------
  3784. if (roundIndex > 0)//1-9测量
  3785. {
  3786. if (res.index < 10)
  3787. {
  3788. //线宽测量
  3789. lock (lstLineWidth)
  3790. {
  3791. double lineWidthValue = res.Shanxian > 0 ? Math.Round(res.Shanxian + confMgr.SysConfigParams.Line_offset, 2) : 0;
  3792. lstLineWidth.Add(lineWidthValue);
  3793. Log($"线宽值", $"线宽{lstLineWidth.Count}:{lineWidthValue}");
  3794. OnAutoRuning(new RunEventArgs(23, lstLineWidth, model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue));
  3795. double LwValue = Math.Round(lstLineWidth.Average(), 2);
  3796. if (order != null)
  3797. order.LineWidthValue = LwValue;
  3798. if (order != null)
  3799. {
  3800. if (lstLineWidth.Count == 1)
  3801. order.LineWidth1 = lineWidthValue;
  3802. else if (lstLineWidth.Count == 2)
  3803. order.LineWidth2 = lineWidthValue;
  3804. else if (lstLineWidth.Count == 3)
  3805. order.LineWidth3 = lineWidthValue;
  3806. else if (lstLineWidth.Count == 4)
  3807. order.LineWidth4 = lineWidthValue;
  3808. else if (lstLineWidth.Count == 5)
  3809. order.LineWidth5 = lineWidthValue;
  3810. else if (lstLineWidth.Count == 6)
  3811. order.LineWidth6 = lineWidthValue;
  3812. else if (lstLineWidth.Count == 7)
  3813. order.LineWidth7 = lineWidthValue;
  3814. else if (lstLineWidth.Count == 8)
  3815. order.LineWidth8 = lineWidthValue;
  3816. else if (lstLineWidth.Count == 9)
  3817. order.LineWidth9 = lineWidthValue;
  3818. }
  3819. double LwUpper = model.LineWidthBaseValue + model.LineWidthUpFloatValue;
  3820. double LwLower = model.LineWidthBaseValue - model.LineWidthDownFloatValue;
  3821. if (LwUpper + LwLower > 0 && (LwValue > LwUpper || LwValue < LwLower))
  3822. order.Qualified = false;
  3823. }
  3824. }
  3825. }
  3826. //校正偏移 10,20,30...:偏移
  3827. else
  3828. {
  3829. AxMoveMode axSizeMode = AxMoveMode.绝对位置;
  3830. double xPos = 0;
  3831. double yPos = 0;
  3832. //绝对偏移
  3833. if (res.offsetX != 0 || res.offsetY != 0)
  3834. {
  3835. xPos += res.offsetX;
  3836. yPos += res.offsetY;
  3837. Log($"{res.stepIndex + 1}-{res.processName}", $"offsetX/Y绝对校正, 0轴:{xPos}mm, 2轴:{yPos}mm");
  3838. }
  3839. else if (res.Circle_Xmm != 0 || res.Circle_Ymm != 0)//相对偏移校正
  3840. {
  3841. axSizeMode = AxMoveMode.相对位置;
  3842. Log($"{res.stepIndex + 1}-{res.processName}", $"原点相对校正, 0轴:{res.Circle_Xmm}mm, 2轴:{res.Circle_Ymm}mm");
  3843. if (res.Circle_Xmm != 0) xPos = res.Circle_Xmm;
  3844. if (res.Circle_Ymm != 0) yPos = res.Circle_Ymm;
  3845. }
  3846. //当前工序直接移动
  3847. if (xPos != 0 || yPos != 0)
  3848. {
  3849. ;
  3850. }
  3851. }
  3852. }
  3853. //失败
  3854. else
  3855. {
  3856. if((res.index == 3333)||(res.index == 1111)||(res.index == 2222)||(res.index == 4444))
  3857. {
  3858. Log($"{res.stepIndex + 1}-{processName}", $"Mark点计算失败,index:{res.index}.", confMgr.SysConfigParams.OpenMarkErrorStop ? WarningEnum.High : WarningEnum.Normal);
  3859. }
  3860. //------TEST
  3861. if (res.index > 20 && res.index < 30)
  3862. {
  3863. //PT测量
  3864. lock (lstPT)
  3865. {
  3866. lstPT.Add(0);
  3867. Log($"PT值", $"PT{lstPT.Count}:0");
  3868. OnAutoRuning(new RunEventArgs(22, lstPT, model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue));
  3869. double PtValue = Math.Round(lstPT.Average(), 4);
  3870. if (order != null)
  3871. order.PTValue = PtValue;
  3872. if (order != null)
  3873. {
  3874. if (lstPT.Count == 1)
  3875. order.PT1 = 0;
  3876. else if (lstPT.Count == 2)
  3877. order.PT2 = 0;
  3878. else if (lstPT.Count == 3)
  3879. order.PT3 = 0;
  3880. else if (lstPT.Count == 4)
  3881. order.PT5 = 0;
  3882. else if (lstPT.Count == 5)
  3883. order.PT6 = 0;
  3884. }
  3885. double PtUpper = model.PTBaseValue + model.PTUpFloatValue;
  3886. double PtLower = model.PTBaseValue - model.PTDownFloatValue;
  3887. if (PtUpper + PtLower > 0 && (PtValue > PtUpper || PtValue < PtLower))
  3888. order.Qualified = false;
  3889. }
  3890. }
  3891. //------
  3892. if (roundIndex > 0)
  3893. {
  3894. if (res.index < 10)
  3895. {
  3896. //线宽测量
  3897. lock (lstLineWidth)
  3898. {
  3899. lstLineWidth.Add(0);
  3900. Log($"线宽值", $"线宽{lstLineWidth.Count}:0");
  3901. OnAutoRuning(new RunEventArgs(23, lstLineWidth, model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue));
  3902. double LwValue = Math.Round(lstLineWidth.Average(), 2);
  3903. if (order != null)
  3904. order.LineWidthValue = LwValue;
  3905. if (order != null)
  3906. {
  3907. if (lstLineWidth.Count == 1)
  3908. order.LineWidth1 = 0;
  3909. else if (lstLineWidth.Count == 2)
  3910. order.LineWidth2 = 0;
  3911. else if (lstLineWidth.Count == 3)
  3912. order.LineWidth3 = 0;
  3913. else if (lstLineWidth.Count == 4)
  3914. order.LineWidth4 = 0;
  3915. else if (lstLineWidth.Count == 5)
  3916. order.LineWidth5 = 0;
  3917. else if (lstLineWidth.Count == 6)
  3918. order.LineWidth6 = 0;
  3919. else if (lstLineWidth.Count == 7)
  3920. order.LineWidth7 = 0;
  3921. else if (lstLineWidth.Count == 8)
  3922. order.LineWidth8 = 0;
  3923. else if (lstLineWidth.Count == 9)
  3924. order.LineWidth9 = 0;
  3925. }
  3926. double LwUpper = model.LineWidthBaseValue + model.LineWidthUpFloatValue;
  3927. double LwLower = model.LineWidthBaseValue - model.LineWidthDownFloatValue;
  3928. if (LwUpper + LwLower > 0 && (LwValue > LwUpper || LwValue < LwLower))
  3929. order.Qualified = false;
  3930. }
  3931. }
  3932. }
  3933. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"失败:{res.resultInfo}"));
  3934. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测失败index:{res.index}:{res.resultInfo}");
  3935. }
  3936. //保存
  3937. if (confMgr.SysConfigParams.SizeBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeBigImag.SavePath))
  3938. {
  3939. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3940. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}.bmp";
  3941. if (res.Himage != null)
  3942. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  3943. else
  3944. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  3945. }
  3946. }
  3947. }
  3948. catch (Exception ex)
  3949. {
  3950. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测回调处理异常 index:{res.index},ex={ex.Message}");
  3951. }
  3952. endEvent.Set();//roundIndex=0成功或失败线程返回
  3953. //---
  3954. if (res.Himage != null)
  3955. {
  3956. res.Himage.Dispose();
  3957. res.Himage = null;
  3958. }
  3959. else
  3960. {
  3961. API.DeleteFile(res.file_path);
  3962. }
  3963. }
  3964. });
  3965. //需等上面异步回调中的相对偏移校正完成再继续
  3966. if (!asynRun || sizeIndex % 10 == 0)
  3967. {
  3968. if (!endEvent.WaitOne(300000))
  3969. Log($"{stepIndex + 1}-{processName}", $"{sizeIndex}等待超时,忽略继续!", WarningEnum.Low);
  3970. }
  3971. #endregion
  3972. break;
  3973. case "Defect":
  3974. #region
  3975. limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
  3976. lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
  3977. if (scannerGBmpQueue.Count < 1)
  3978. {
  3979. Log($"{stepIndex + 1}-{processName}", $"缺陷检测异常,无源图像!!", WarningEnum.Low);
  3980. return stepIndex;
  3981. }
  3982. var bmpLoc = scannerGBmpQueue.Dequeue();
  3983. Log($"{stepIndex + 1}-{processName}", $"开始缺陷检测,源图索引:{defectBmpNum},图像队列数量: {scannerGBmpQueue.Count}...");
  3984. string[] aarCut_size = processParam.Value<string>("CutSize").Split(',');
  3985. string[] aarResize = processParam.Value<string>("Resize").Split(',');
  3986. //图纸
  3987. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  3988. if (attachmentFile != null)
  3989. {
  3990. gbxBmpPath = ConfMgr.Instance.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  3991. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName)) gbxBmpPath = "";
  3992. }
  3993. Log($"{stepIndex + 1}-{processName}", $"图纸路径:{gbxBmpPath}");
  3994. int err = 1;
  3995. string modeltp = "pt";
  3996. //Classes tClasses = svcClasses.GetById(model.ClassesId);
  3997. //if (tClasses != null)
  3998. //{
  3999. // if (tClasses.Name == "乳剂")
  4000. // modeltp = "rj";
  4001. // else
  4002. // modeltp = "pt";
  4003. //}
  4004. if (model.DefectModelFile.Replace(".onnx", "") == "rj")
  4005. modeltp = "rj";
  4006. else
  4007. modeltp = "pt";
  4008. err = 2;
  4009. defectLib.add(new DefectTask()
  4010. {
  4011. modelType = modeltp,
  4012. stepIndex = stepIndex,
  4013. processName = processName,
  4014. drawingPagePath = gbxBmpPath,
  4015. //index = defectBmpNum++,
  4016. index = defectBmpNum,
  4017. bmp = bmpLoc.bmp.Clone(),
  4018. Xmm = bmpLoc.Xmm,
  4019. Ymm = bmpLoc.Ymm,
  4020. cut_size = new System.Drawing.Size(Convert.ToInt32(aarCut_size[0]), Convert.ToInt32(aarCut_size[1])),
  4021. resize = new System.Drawing.Size(Convert.ToInt32(aarResize[0]), Convert.ToInt32(aarResize[1])),
  4022. thresholds = processParam.Value<float>("Thresholds"),
  4023. //thresholdsClass = processParam.Value<string>("ThresholdsClass"),
  4024. thresholdsClass = getProductThresholClass(model, processParam.Value<string>("ThresholdsClass")),
  4025. recAreaThreshold = getProductAreaThreshol(model), //qxName,面积; qxName,面积; qxName,面积;
  4026. finishEvent = (res) =>
  4027. {
  4028. if (res.isSucceed)
  4029. {
  4030. //界面显示
  4031. OnAutoRuning(new RunEventArgs(liStatocStepIndex,
  4032. $"源图索引:{res.index},缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}"));
  4033. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测完成(源图索引:{res.index}),缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}");
  4034. string path = "";
  4035. if (res.defectCount > 0)
  4036. {
  4037. //UI显示小图 (含统计缺陷类型数量)
  4038. AllDefectCount += res.informationList.Count;
  4039. showDefectSmallBmps(res.bmps_tag, res.bmps_cut, res.Xmm, res.Ymm, res.informationList);
  4040. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  4041. {
  4042. Log($"{res.stepIndex + 1}-{res.processName}", $"转换后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
  4043. if (order.DefectInfoList == null)
  4044. order.DefectInfoList = new List<DefectInfo>();
  4045. foreach (var item in res.defectInfor2RestorationDeskPage)
  4046. order.DefectInfoList.Add(new DefectInfo()
  4047. {
  4048. Type = 0,
  4049. Code = item[3],
  4050. X = double.Parse(item[1]),
  4051. Y = double.Parse(item[2]),
  4052. ZXD = double.Parse(item[4]),
  4053. Index = int.Parse(item[0]),
  4054. Area = item.Count > 5 ? double.Parse(item[5]) : 0,
  4055. ModifyUserCode = UserMgr.LoginUser.Code,
  4056. CreateUserCode = UserMgr.LoginUser.Code,
  4057. });
  4058. }
  4059. //保存原始大图
  4060. if (confMgr.SysConfigParams.DefectBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectBigImag.SavePath))
  4061. {
  4062. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  4063. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{model.StepInfo.Name}";
  4064. lock (ImageSaveObj)
  4065. {
  4066. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
  4067. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.informationList));
  4068. }
  4069. }
  4070. //保存小图
  4071. if (confMgr.SysConfigParams.DefectSmallImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectSmallImag.SavePath))
  4072. {
  4073. //2024-03-07 图片index计算
  4074. List<string> indexList = new List<string>();
  4075. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  4076. foreach (var item in res.defectInfor2RestorationDeskPage)
  4077. {
  4078. if (indexList.Count == 0)
  4079. indexList.Add(item[0]);
  4080. else
  4081. {
  4082. if (!indexList.Contains(item[0]))
  4083. indexList.Add(item[0]);
  4084. }
  4085. }
  4086. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectSmallImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  4087. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_{model.StepInfo.Name}";
  4088. if (res.bmps_tag.Count() != indexList.Count)
  4089. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷图片张数和index对不上:{res.bmps_tag.Count()} - {indexList.Count}", WarningEnum.Low);
  4090. for (int i = 0; i < res.bmps_tag.Count(); i++)
  4091. {
  4092. lock (ImageSaveObj)
  4093. {
  4094. if (res.bmps_tag.Count() != indexList.Count)
  4095. res.bmps_tag[i].Save(path + $"_i{i}_{i}.bmp", ImageFormat.Bmp);
  4096. else
  4097. res.bmps_tag[i].Save(path + $"_i{i}_{indexList[i]}.bmp", ImageFormat.Bmp);
  4098. }
  4099. //res.bmps_tag[i].Save(path + $"_i{i}.bmp", ImageFormat.Bmp);
  4100. //res.bmps_tag[i].Save(path + $"{indexList[i]}.bmp", ImageFormat.Bmp);
  4101. }
  4102. }
  4103. //保存原始小图
  4104. if (confMgr.SysConfigParams.DefectSrcSmallImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectSrcSmallImag.SavePath))
  4105. {
  4106. Log($"{res.stepIndex + 1}-{res.processName}", $"原始小图保存");
  4107. string sinfo = "";
  4108. int sterr = 0;
  4109. try
  4110. {
  4111. for (int i = 0; i < res.defectInfor2RestorationDesk.Count(); i++)
  4112. {
  4113. sterr = 1;
  4114. sinfo = JsonConvert.SerializeObject(res.defectInfor2RestorationDesk[i]);
  4115. int indext = int.Parse(res.defectInfor2RestorationDesk[i][0]);
  4116. double thres = double.Parse(res.defectInfor2RestorationDesk[i][4]);
  4117. if (thres >= confMgr.SysConfigParams.Defect_SrcSmall_Thres)
  4118. {
  4119. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectSrcSmallImag.SavePath,
  4120. new List<string> { order.CreateTime.ToString("yyyyMMdd"),
  4121. model.MainGrid == 1?"主栅":model.DefectModelFile.IndexOf("rj") >= 0?"rj":model.DefectModelFile.IndexOf("pi") >= 0?"pi" : "其他",
  4122. order.SN,
  4123. res.defectInfor2RestorationDesk[i][3]});
  4124. sterr = 2;
  4125. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_{model.StepInfo.Name}";
  4126. res.bmps_cut[indext].ImWrite(path + $"_i{i}.bmp");
  4127. sterr = 3;
  4128. }
  4129. }
  4130. }
  4131. catch (Exception ex)
  4132. {
  4133. Log($"{res.stepIndex + 1}-{res.processName}", $"原始小图保存出错{sterr}-{sinfo}-{path}:{ex.Message}");
  4134. }
  4135. }
  4136. //保存压缩大图 -- 用于修复台调用
  4137. if (confMgr.SysConfigParams.DefectRepairImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectRepairImag.SavePath))
  4138. {
  4139. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectRepairImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  4140. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{model.StepInfo.Name}";
  4141. lock (ImageSaveObj)
  4142. {
  4143. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmpCompress).Save(path + ".bmp", ImageFormat.Bmp);
  4144. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
  4145. }
  4146. }
  4147. }
  4148. else//没有缺陷
  4149. {
  4150. if (confMgr.SysConfigParams.SaveAllImg && confMgr.SysConfigParams.DefectBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectBigImag.SavePath))
  4151. {
  4152. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  4153. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{model.StepInfo.Name}";
  4154. lock (ImageSaveObj)
  4155. {
  4156. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
  4157. }
  4158. }
  4159. }
  4160. }
  4161. else
  4162. {
  4163. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"失败:{res.resultInfo}"));
  4164. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测失败:{res.resultInfo}");
  4165. //暂停 这里不能暂停,stepIndex和scannerBmpQueue队列也不对了
  4166. }
  4167. defectBmpNumResult++;
  4168. foreach (var item in res.bmps_cut)
  4169. item.Dispose();
  4170. res.bmp.Dispose();
  4171. res.bmp = null;
  4172. res.bmps_tag = null;
  4173. if (res.bmpCompress != null)
  4174. {
  4175. res.bmpCompress.Dispose();
  4176. res.bmpCompress = null;
  4177. }
  4178. System.GC.Collect();
  4179. }
  4180. });
  4181. defectBmpNum++;
  4182. #endregion
  4183. break;
  4184. case "For":
  4185. #region
  4186. long UniqueId = processParam.Value<long>("UniqueId");
  4187. int GotoStepIndex = processParam.Value<int>("GotoStepIndex");//1-n
  4188. int LimitNum = processParam.Value<int>("LimitNum");//1-n
  4189. bool Reset = processParam.Value<bool>("Reset");
  4190. if (GotoStepIndex - 1 == stepIndex)
  4191. {
  4192. Log($"{stepIndex + 1}-{processName}", $"For死循环!!!", WarningEnum.High);
  4193. return stepIndex;
  4194. }
  4195. if (!forLib.dicData.ContainsKey(UniqueId))
  4196. forLib.dicData.Add(UniqueId, 0);
  4197. //
  4198. int Num = forLib.dicData[UniqueId];
  4199. Num++;
  4200. if (Num <= LimitNum)
  4201. {
  4202. if (Num == LimitNum)
  4203. {
  4204. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num}/{LimitNum}]次,循环完成"));
  4205. Log($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次,循环完成。");
  4206. }
  4207. else
  4208. {
  4209. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num}/{LimitNum}]次"));
  4210. Log($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次跳转到步骤[{GotoStepIndex}]...");
  4211. stepIndex = GotoStepIndex - 2;
  4212. }
  4213. forLib.dicData[UniqueId] = Num;
  4214. }
  4215. else
  4216. {
  4217. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"已失效不执行"));
  4218. Log($"{stepIndex + 1}-{processName}", $"本循环已失效不执行!");
  4219. }
  4220. //达到limit重置0
  4221. if (forLib.dicData[UniqueId] >= LimitNum && Reset)
  4222. {
  4223. forLib.dicData[UniqueId] = 0;
  4224. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[0/{LimitNum}]次"));
  4225. Log($"{stepIndex + 1}-{processName}", $"计数器已重置。");
  4226. }
  4227. #endregion
  4228. break;
  4229. case "If":
  4230. #region
  4231. long UniqueId_if = processParam.Value<long>("UniqueId");
  4232. int GotoStepIndex_if = processParam.Value<int>("GotoStepIndex");//1-n
  4233. int LimitNum_if = processParam.Value<int>("LimitNum");//1-n
  4234. bool Reset_if = processParam.Value<bool>("Reset");
  4235. if (GotoStepIndex_if - 1 == stepIndex)
  4236. {
  4237. Log($"{stepIndex + 1}-{processName}", $"If死循环,不可自我跳转!!!", WarningEnum.High);
  4238. return stepIndex;
  4239. }
  4240. //
  4241. if (!ifLib.dicData.ContainsKey(UniqueId_if))
  4242. ifLib.dicData.Add(UniqueId_if, 0);
  4243. //
  4244. int Num_if = ifLib.dicData[UniqueId_if];
  4245. Num_if++;
  4246. if (Num_if <= LimitNum_if)
  4247. {
  4248. if (Num_if == LimitNum_if)
  4249. {
  4250. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num_if}/{LimitNum_if}]次,跳转至[{GotoStepIndex_if}]"));
  4251. Log($"{stepIndex + 1}-{processName}", $"计数器[{Num_if}/{LimitNum_if}],跳转至步骤[{GotoStepIndex_if}]...");
  4252. stepIndex = GotoStepIndex_if - 2;
  4253. }
  4254. else
  4255. {
  4256. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num_if}/{LimitNum_if}]次,不跳转"));
  4257. Log($"{stepIndex + 1}-{processName}", $"计数器[{Num_if}/{LimitNum_if}],不跳转。");
  4258. }
  4259. //
  4260. ifLib.dicData[UniqueId_if] = Num_if;
  4261. }
  4262. else
  4263. {
  4264. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"已失效不执行"));
  4265. Log($"{stepIndex + 1}-{processName}", $"本IF已失效不执行。");
  4266. }
  4267. //达到limit重置0
  4268. if (ifLib.dicData[UniqueId_if] >= LimitNum_if && Reset_if)
  4269. {
  4270. ifLib.dicData[UniqueId_if] = 0;
  4271. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[0/{LimitNum_if}]次"));
  4272. Log($"{stepIndex + 1}-{processName}", $"计数器已重置。");
  4273. }
  4274. #endregion
  4275. break;
  4276. default:
  4277. Log($"{stepIndex + 1}-{processName}", $"未知工序:{processInfo.ProcessCode}", WarningEnum.High);
  4278. return stepIndex;
  4279. }
  4280. if (sleepLater > 0) Thread.Sleep((int)sleepLater);
  4281. #endregion
  4282. }
  4283. else
  4284. {
  4285. #region 新流程/快速流程
  4286. #region 参数
  4287. int AxisX1 = (int)AxisName.Axis0;
  4288. int AxisX2 = (int)AxisName.Axis1;
  4289. int AxisY = (int)AxisName.Axis2;
  4290. int AxisZ = (int)AxisName.Axis3;
  4291. TestCnt = 0;
  4292. int liStatocStepIndex = stepIndex;
  4293. int DelayTime = 0;
  4294. int DataCnt = 0;
  4295. double OffsetValue = 0;
  4296. DataProcess dataProcess = DataProcess.均值;
  4297. DataJudgment judgmentData = DataJudgment.均值;
  4298. List<PointF> Points = new List<PointF>();
  4299. double VelLow = 0;
  4300. double VelHigh = 0;
  4301. double Acc = 0;
  4302. double Dec = 0;
  4303. int WaitTime = 0;
  4304. double upLimit = 0;
  4305. double loLimit = 0;
  4306. List<double> tempDataList = new List<double>();
  4307. Models.Attachment attachmentFile;
  4308. string gbxBmpPath = "";
  4309. List<string> testLabels = new List<string>();
  4310. foreach (var item in confMgr.SizeItemParamsList)
  4311. {
  4312. //名称可以直接获取
  4313. testLabels.Add(item.Name);
  4314. }
  4315. #endregion
  4316. switch (processInfo.ProcessCode)
  4317. {
  4318. case "Tension":
  4319. #region 张力测试
  4320. if (confMgr.SysConfigParams.DisableTensor)
  4321. {
  4322. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4323. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4324. break;
  4325. }
  4326. if (!SizeEnable)
  4327. {
  4328. Log($"{stepIndex + 1}-{processName}", $"尺寸检测功能禁用,忽略此步骤!");
  4329. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"尺寸检测功能禁用,忽略此步骤!", 0, false));
  4330. break;
  4331. }
  4332. TestCnt = processParam.Value<int>("TestCnt");
  4333. dataProcess = (DataProcess)processParam.Value<int>("ProcessData");
  4334. DelayTime = processParam.Value<int>("DelayTime");
  4335. DataCnt = processParam.Value<int>("DataCnt");
  4336. OffsetValue = processParam.Value<double>("OffsetValue");
  4337. judgmentData = (DataJudgment)processParam.Value<int>("JudgmentData");
  4338. TensionProp TensionParam = JsonConvert.DeserializeObject<TensionProp>(jsonParams);
  4339. //显示当前测试
  4340. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "张力读取", lstTension, 0, 0, 0, 1, false));
  4341. while (true)
  4342. {
  4343. if (isBreakProcessRun())
  4344. return stepIndex;
  4345. bool sts = false;
  4346. double tensionValue = 0;
  4347. double tensionJudgValue = 0;
  4348. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.触发张力), GetIOBitIndex((int)DIName.触发张力), out sts);
  4349. if( sts )
  4350. {
  4351. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.触发张力按钮灯), GetIOBitIndex((int)DOName.触发张力按钮灯), true);
  4352. tempDataList = new List<double>();
  4353. for (int i = 0; i < DataCnt; i++)
  4354. {
  4355. //Thread.Sleep(DelayTime);
  4356. Thread.Sleep(100);
  4357. tensionValue = TensionGetValueNewStep();
  4358. if (tensionValue < 0)
  4359. {
  4360. if(tensionValue == -1)
  4361. Log("张力读取", "张力读取失败,忽略此次测试!");
  4362. else
  4363. Log("张力读取", "张力读取失败且处理失败,忽略此次测试!");
  4364. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.触发张力按钮灯), GetIOBitIndex((int)DOName.触发张力按钮灯), false);
  4365. return stepIndex;
  4366. }
  4367. tempDataList.Add( tensionValue );
  4368. }
  4369. switch(dataProcess)
  4370. {
  4371. case DataProcess.均值:
  4372. tensionValue = tempDataList.Average();
  4373. break;
  4374. case DataProcess.最大值:
  4375. tensionValue = tempDataList.Max();
  4376. break;
  4377. case DataProcess.最小值:
  4378. tensionValue = tempDataList.Min();
  4379. break;
  4380. default:
  4381. tensionValue = tempDataList.Average();
  4382. Log("张力读取", "张力读取处理错误,启用均值!");
  4383. break;
  4384. }
  4385. tensionValue = Math.Round(tensionValue, 2);
  4386. Log("张力读取", $"张力值:{tensionValue}, 补偿值:{OffsetValue}");
  4387. tensionValue = tensionValue + OffsetValue;
  4388. lstTension.Add(tensionValue);
  4389. Thread.Sleep(200);
  4390. //获取判断结果
  4391. if (judgmentData == DataJudgment.单点)
  4392. tensionJudgValue = tensionValue;
  4393. else
  4394. tensionJudgValue = Math.Round(lstTension.Average(), 2);
  4395. if (TensionParam.OpenUseLimit)
  4396. {
  4397. upLimit = TensionParam.StandardValues + TensionParam.MaxLimit;
  4398. loLimit = TensionParam.StandardValues - TensionParam.MinLimit;
  4399. }
  4400. else
  4401. {
  4402. upLimit = CurrProductModel.TensionBaseValue + CurrProductModel.TensionUpFloatValue;
  4403. loLimit = CurrProductModel.TensionBaseValue - CurrProductModel.TensionDownFloatValue;
  4404. }
  4405. if (((upLimit+ loLimit)>0)&&(tensionJudgValue > upLimit) || (tensionJudgValue < loLimit))
  4406. {
  4407. CurrStepResult = 2;
  4408. //order.Qualified = false;
  4409. }
  4410. else if ((judgmentData == DataJudgment.均值)
  4411. && (upLimit + loLimit > 0 && !(tensionJudgValue > upLimit || tensionJudgValue < loLimit)))
  4412. {
  4413. //order.Qualified = true;
  4414. CurrStepResult = 0;
  4415. }
  4416. order.TensionValue = Math.Round(lstTension.Average(),2);
  4417. if (order.SizeDefectInfoList == null)
  4418. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  4419. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  4420. {
  4421. result = CurrStepResult == 2 ? 2:1,
  4422. X = 0,
  4423. Y = 0,
  4424. PointCode = processInfo.ProcessCode,
  4425. Data = tensionValue,
  4426. StepName = processName,
  4427. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4428. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4429. isAverage = false
  4430. });
  4431. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.触发张力按钮灯), GetIOBitIndex((int)DOName.触发张力按钮灯), false);
  4432. //显示数据
  4433. if ((TestCnt - 1) == this.CurrPoinntCount) //显示最终结果
  4434. {
  4435. order.Qualified = CurrStepResult > 0 ? false : order.Qualified;
  4436. //记录均值
  4437. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  4438. {
  4439. result = CurrStepResult == 2 ? 2 : 1,
  4440. X = 0,
  4441. Y = 0,
  4442. PointCode = processInfo.ProcessCode,
  4443. Data = Math.Round(lstTension.Average(), 2),
  4444. StepName = processName,
  4445. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4446. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4447. isAverage = true
  4448. });
  4449. //打印
  4450. PrintDataList(processName, TensionParam, CurrProductModel.TensionBaseValue, CurrProductModel.TensionUpFloatValue, CurrProductModel.TensionDownFloatValue);
  4451. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "张力读取", lstTension, Math.Round(lstTension.Average(), 2),
  4452. Math.Round(lstTension.Max(), 2), Math.Round(lstTension.Min(), 2), CurrStepResult > 0 ? 3 : 2, false));
  4453. }
  4454. else
  4455. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "张力读取", lstTension, Math.Round(lstTension.Average(), 2),
  4456. Math.Round(lstTension.Max(), 2), Math.Round(lstTension.Min(), 2), 1, false));
  4457. break;
  4458. }
  4459. Thread.Sleep(100);
  4460. }
  4461. Thread.Sleep(DelayTime);
  4462. #endregion
  4463. break;
  4464. case "Height":
  4465. #region 厚度测试
  4466. if (confMgr.SysConfigParams.DisableThickness)
  4467. {
  4468. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4469. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4470. break;
  4471. }
  4472. if (!SizeEnable)
  4473. {
  4474. Log($"{stepIndex + 1}-{processName}", $"尺寸检测功能禁用,忽略此步骤!");
  4475. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"尺寸检测功能禁用,忽略此步骤!", 0, false));
  4476. break;
  4477. }
  4478. //判断厚度基准打完
  4479. while (true)
  4480. {
  4481. if (isBreakProcessRun())
  4482. return stepIndex;
  4483. if (IsCurrHeightBase)
  4484. break;
  4485. Thread.Sleep(100);
  4486. }
  4487. //判断是否需要使用双控
  4488. if(!WaitGetStartSig())
  4489. {
  4490. return stepIndex;
  4491. }
  4492. if (!WaitAllAxisDone())//因启用轴异步功能,使用前需等待
  4493. {
  4494. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  4495. return stepIndex;
  4496. }
  4497. TestCnt = processParam.Value<int>("TestCnt");
  4498. dataProcess = (DataProcess)processParam.Value<int>("ProcessData");
  4499. judgmentData = (DataJudgment)processParam.Value<int>("JudgmentData");
  4500. DelayTime = processParam.Value<int>("DelayTime");
  4501. DataCnt = processParam.Value<int>("DataCnt");
  4502. OffsetValue = processParam.Value<double>("OffsetValue") + confMgr.SysConfigParams.Thickness_Offset;
  4503. //Points = processParam.Value<List<PointF>>("Points");
  4504. ThicknessProp thicknessParam = JsonConvert.DeserializeObject<ThicknessProp>(jsonParams);
  4505. Points = thicknessParam.Points;
  4506. VelLow = processParam.Value<double>("VelLow");
  4507. VelHigh = processParam.Value<double>("VelHigh");
  4508. Acc = processParam.Value<double>("Acc");
  4509. Dec = processParam.Value<double>("Dec");
  4510. WaitTime = processParam.Value<int>("WaitTime");
  4511. ThicknessProp ThicknessParam = JsonConvert.DeserializeObject<ThicknessProp>(jsonParams);
  4512. Log($"{stepIndex + 1}-{processName}", processParam.ToString());
  4513. if (TestCnt > Points.Count)
  4514. {
  4515. Log($"{stepIndex + 1}-{processName}", $"点位少于测试次数!", WarningEnum.High);
  4516. return stepIndex;
  4517. }
  4518. Log($"{stepIndex + 1}-{processName}", $"点位{this.CurrPoinntCount + 1}测试");
  4519. Log($"{stepIndex + 1}-{processName}",
  4520. $"XY准备(绝对)运动至{Points[this.CurrPoinntCount].X},{Points[this.CurrPoinntCount].Y}...");
  4521. if (axisDev.CheckDone(AxisX1, 20) != 0)
  4522. {
  4523. Log($"{stepIndex + 1}-{processName}", $"轴X1到位失败!", WarningEnum.High);
  4524. return stepIndex;
  4525. }
  4526. if (axisDev.CheckDone(AxisY, 20) != 0)
  4527. {
  4528. Log($"{stepIndex + 1}-{processName}", $"轴Y到位失败!", WarningEnum.High);
  4529. return stepIndex;
  4530. }
  4531. VelocityCurveParams velx = new VelocityCurveParams(Acc, Dec, VelLow, VelHigh, MotionST, GetMMtoPlus((AxisName)AxisX1));
  4532. VelocityCurveParams vely = new VelocityCurveParams(Acc, Dec, VelLow, VelHigh, MotionST, GetMMtoPlus((AxisName)AxisY));
  4533. int iret1 = 0;
  4534. int iret2 = 0;
  4535. iret1 = axisDev.MoveAbsValue(AxisX1, velx, Points[this.CurrPoinntCount].X);
  4536. iret2 = axisDev.MoveAbsValue(AxisY, vely, Points[this.CurrPoinntCount].Y);
  4537. if (iret1 != 0)
  4538. {
  4539. Log($"{stepIndex + 1}-{processName}", $"轴X1运动失败!", WarningEnum.High);
  4540. return stepIndex;
  4541. }
  4542. if (iret2 != 0)
  4543. {
  4544. Log($"{stepIndex + 1}-{processName}", $"轴Y运动失败!", WarningEnum.High);
  4545. return stepIndex;
  4546. }
  4547. //多轴同时运行后强制等待各轴完成
  4548. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  4549. if (axisDev.CheckDone(AxisX1, 20) != 0)
  4550. {
  4551. Log($"{stepIndex + 1}-{processName}", $"轴X1到位失败!", WarningEnum.High);
  4552. return stepIndex;
  4553. }
  4554. if (axisDev.CheckDone(AxisY, 20) != 0)
  4555. {
  4556. Log($"{stepIndex + 1}-{processName}", $"轴Y到位失败!", WarningEnum.High);
  4557. return stepIndex;
  4558. }
  4559. Thread.Sleep(WaitTime);
  4560. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  4561. //测厚气缸下降
  4562. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), true);
  4563. Thread.Sleep(confMgr.HeightDoWait);
  4564. //读取数据
  4565. double TempVal = 0;
  4566. tempDataList = new List<double>();
  4567. for (int j = 0; j < DataCnt; j++)
  4568. {
  4569. Thread.Sleep(DelayTime);
  4570. TempVal = thicknessDev.GetValue();
  4571. tempDataList.Add(TempVal);
  4572. }
  4573. switch (dataProcess)
  4574. {
  4575. case DataProcess.均值:
  4576. TempVal = tempDataList.Average();
  4577. break;
  4578. case DataProcess.最大值:
  4579. TempVal = tempDataList.Max();
  4580. break;
  4581. case DataProcess.最小值:
  4582. TempVal = tempDataList.Min();
  4583. break;
  4584. default:
  4585. TempVal = tempDataList.Average();
  4586. Log("厚度读取", "厚度读取处理错误,启用均值!");
  4587. break;
  4588. }
  4589. TempVal = Math.Round(TempVal, 2);
  4590. double TestValue = Math.Round(Math.Abs(lstHeightBase[this.CurrPoinntCount] - TempVal) + OffsetValue,2);
  4591. Log("厚度读取", $"厚度值{this.CurrPoinntCount + 1}:{TestValue},读取值:{TempVal},基准值:{lstHeightBase[this.CurrPoinntCount]},补偿值:{OffsetValue}");
  4592. lstHeight.Add(TestValue);
  4593. //测厚气缸上升
  4594. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), false);
  4595. Thread.Sleep(confMgr.HeightDoWait);
  4596. //获取判断结果
  4597. double JudgValue;
  4598. if (judgmentData == DataJudgment.单点)
  4599. JudgValue = TestValue;
  4600. else
  4601. JudgValue = Math.Round(lstHeight.Average(), 2);
  4602. if (ThicknessParam.OpenUseLimit)
  4603. {
  4604. upLimit = ThicknessParam.StandardValues + ThicknessParam.MaxLimit;
  4605. loLimit = ThicknessParam.StandardValues - ThicknessParam.MinLimit;
  4606. }
  4607. else
  4608. {
  4609. upLimit = CurrProductModel.HeightBaseValue + CurrProductModel.HeightUpFloatValue;
  4610. loLimit = CurrProductModel.HeightBaseValue - CurrProductModel.HeightDownFloatValue;
  4611. }
  4612. if (((upLimit + loLimit) > 0) && (JudgValue > upLimit) || (JudgValue < loLimit))
  4613. {
  4614. CurrStepResult = 2;
  4615. //order.Qualified = false;
  4616. }
  4617. else if ((judgmentData == DataJudgment.均值)
  4618. && (upLimit + loLimit > 0 && !(JudgValue > upLimit || JudgValue < loLimit)))
  4619. {
  4620. //order.Qualified = true;
  4621. CurrStepResult = 0;
  4622. }
  4623. order.HeightValue = Math.Round(lstHeight.Average(),2);
  4624. if (order.SizeDefectInfoList == null)
  4625. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  4626. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  4627. {
  4628. result = CurrStepResult == 2 ? 2 : 1,
  4629. X = Points[this.CurrPoinntCount].X,
  4630. Y = Points[this.CurrPoinntCount].Y,
  4631. PointCode = processInfo.ProcessCode,
  4632. Data = TestValue,
  4633. StepName = processName,
  4634. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4635. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4636. isAverage = false
  4637. });
  4638. //显示数据
  4639. if ((TestCnt - 1) == this.CurrPoinntCount) //显示最终结果
  4640. {
  4641. order.Qualified = CurrStepResult > 0 ? false : order.Qualified;
  4642. //记录均值
  4643. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  4644. {
  4645. result = CurrStepResult == 2 ? 2 : 1,
  4646. X = Points[this.CurrPoinntCount].X,
  4647. Y = Points[this.CurrPoinntCount].Y,
  4648. PointCode = processInfo.ProcessCode,
  4649. Data = Math.Round(lstHeight.Average(), 2),
  4650. StepName = processName,
  4651. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4652. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4653. isAverage = true
  4654. });
  4655. //打印记录
  4656. PrintDataList(processName, thicknessParam, CurrProductModel.HeightBaseValue, CurrProductModel.HeightUpFloatValue,
  4657. CurrProductModel.HeightDownFloatValue);
  4658. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "厚度读取", lstHeight, Math.Round(lstHeight.Average(), 2),
  4659. Math.Round(lstHeight.Max(), 2), Math.Round(lstHeight.Min(), 2), CurrStepResult > 0 ? 3 : 2, false));
  4660. }
  4661. else
  4662. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "厚度读取", lstHeight, Math.Round(lstHeight.Average(), 2),
  4663. Math.Round(lstHeight.Max(), 2), Math.Round(lstHeight.Min(), 2), 1, false));
  4664. #endregion
  4665. break;
  4666. case "LensMotor":
  4667. #region 镜头
  4668. if (confMgr.SysConfigParams.DisableLensMotor)
  4669. {
  4670. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4671. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4672. break;
  4673. }
  4674. LensProp lensParam = JsonConvert.DeserializeObject<LensProp>(jsonParams);
  4675. //无点位,所以设置为1次执行或0次
  4676. TestCnt = 0;
  4677. //判断是否需要使用双控
  4678. if (!WaitGetStartSig())
  4679. {
  4680. return stepIndex;
  4681. }
  4682. //显示当前测试
  4683. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "镜头变焦", new List<double>(),
  4684. lensParam.AutoFocus ? 0 : 1, lensParam.AutoMotor ? 0 : 1, lensParam.AutoZPoints ? 0 : 1, 1, false));
  4685. //开启自动变倍
  4686. if (lensParam.AutoMotor)
  4687. {
  4688. Log($"{stepIndex + 1}-{processName}", $"开始自动变倍,由起始位置{lensMotorDev.GetFeedbackPos(0)}运动到{lensParam.FcousPos}...");
  4689. lensMotorDev.MoveAbsPulse(0, new VelocityCurveParams(), (int)lensParam.FcousPos);
  4690. }
  4691. else
  4692. {
  4693. Log($"{stepIndex + 1}-{processName}", $"开始手动变倍,由起始位置{lensMotorDev.GetFeedbackPos(0)}运动到{lensParam.MotorPulse}...");
  4694. lensMotorDev.MoveAbsPulse(0, new VelocityCurveParams(), lensParam.MotorPulse);
  4695. }
  4696. VelocityCurveParams vel_z = new VelocityCurveParams(DefaultSpeed / 2, DefaultSpeed / 2, 0, DefaultSpeed / 2, 1, GetMMtoPlus(AxisName.Axis3));
  4697. //开启自动对焦
  4698. if (lensParam.AutoZPoints)
  4699. {
  4700. double zpos = 0;
  4701. switch (lensParam.FcousPos)
  4702. {
  4703. case SmallAxCmdPos.倍率0_58X:
  4704. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_0_58X;
  4705. break;
  4706. case SmallAxCmdPos.倍率1_0X:
  4707. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_1_0X;
  4708. break;
  4709. case SmallAxCmdPos.倍率1_5X:
  4710. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_1_5X;
  4711. break;
  4712. case SmallAxCmdPos.倍率2_0X:
  4713. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_2_0X;
  4714. break;
  4715. case SmallAxCmdPos.倍率2_5X:
  4716. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_2_5X;
  4717. break;
  4718. case SmallAxCmdPos.倍率3_0X:
  4719. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_3_0X;
  4720. break;
  4721. case SmallAxCmdPos.倍率3_5X:
  4722. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_3_5X;
  4723. break;
  4724. case SmallAxCmdPos.倍率4_0X:
  4725. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_4_0X;
  4726. break;
  4727. case SmallAxCmdPos.倍率4_5X:
  4728. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_4_5X;
  4729. break;
  4730. case SmallAxCmdPos.倍率5_0X:
  4731. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_5_0X;
  4732. break;
  4733. case SmallAxCmdPos.倍率5_5X:
  4734. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_5_5X;
  4735. break;
  4736. case SmallAxCmdPos.倍率6_0X:
  4737. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_6_0X;
  4738. break;
  4739. case SmallAxCmdPos.倍率6_5X:
  4740. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_6_5X;
  4741. break;
  4742. case SmallAxCmdPos.倍率7_0X:
  4743. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_7_0X;
  4744. break;
  4745. case SmallAxCmdPos.倍率7_5X:
  4746. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_7_5X;
  4747. break;
  4748. default:
  4749. zpos = 0;
  4750. break;
  4751. }
  4752. Log($"{stepIndex + 1}-{processName}", $"开始自动Z轴对焦,运动到{zpos}...");
  4753. axisDev.MoveAbsValue(AxisZ, vel_z, zpos);
  4754. }
  4755. else
  4756. {
  4757. Log($"{stepIndex + 1}-{processName}", $"开始手动Z轴对焦,运动到{lensParam.ZPoints}...");
  4758. axisDev.MoveAbsValue(AxisZ, vel_z, lensParam.ZPoints);
  4759. }
  4760. //判断到位
  4761. lensMotorDev.CheckDone(0, 10000);
  4762. if (axisDev.CheckDone(AxisZ, 20) != 0)
  4763. {
  4764. Log($"{stepIndex + 1}-{processName}", $"轴Z到位失败!", WarningEnum.High);
  4765. return stepIndex;
  4766. }
  4767. Log($"{stepIndex + 1}-{processName}", $"运动完成,当前镜头位置:{lensMotorDev.GetFeedbackPos(0)},Z轴位置:{axisDev.GetFeedbackPos(AxisZ)/ GetMMtoPlus(AxisName.Axis3)}");
  4768. //自动对焦,开启后之后测试启用
  4769. this.IsAutoFocus = lensParam.AutoFocus;
  4770. this.FocusStep = lensParam.FocusStep;
  4771. this.DirStep = lensParam.DirStep;
  4772. this.DirWaitTime = lensParam.WaitTime;
  4773. this.FocusTimeOut = lensParam.TimeOut;
  4774. //显示完成
  4775. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "镜头变焦", new List<double>(),
  4776. lensParam.AutoFocus ? 0 : 1, lensParam.AutoMotor ? 0 : 1, lensParam.AutoZPoints ? 0 : 1, 2, false));
  4777. #endregion
  4778. break;
  4779. case "Light":
  4780. #region 光源
  4781. if (confMgr.SysConfigParams.DisableLight)
  4782. {
  4783. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4784. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4785. break;
  4786. }
  4787. //判断是否需要使用双控
  4788. if (!WaitGetStartSig())
  4789. {
  4790. return stepIndex;
  4791. }
  4792. //无点位,所以设置为1次执行或0次
  4793. TestCnt = 0;
  4794. LightProp lightParam = JsonConvert.DeserializeObject<LightProp>(jsonParams);
  4795. //显示当前测试
  4796. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "光源设置", new List<double>(), 0, lightParam.ChannelIndex, lightParam.DigitalValue, 1, false));
  4797. int nowDiaitalValue = lightDev.GetLightDigitalValue(lightParam.ChannelIndex);
  4798. Log($"{stepIndex + 1}-{processName}", $"通道{lightParam.ChannelIndex}当前值:{nowDiaitalValue},准备更新值:{lightParam.DigitalValue}...");
  4799. lightDev.SetLightDigitalValue(lightParam.ChannelIndex, lightParam.DigitalValue);
  4800. nowDiaitalValue = lightDev.GetLightDigitalValue(lightParam.ChannelIndex);
  4801. Log($"{stepIndex + 1}-{processName}", $"通道{lightParam.ChannelIndex}更新后当前值:{nowDiaitalValue}。");
  4802. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "光源设置", new List<double>(), 0, lightParam.ChannelIndex, lightParam.DigitalValue, 2, false));
  4803. #endregion
  4804. break;
  4805. case "Mark":
  4806. #region Mark
  4807. MarkProp markParam = JsonConvert.DeserializeObject<MarkProp>(jsonParams);
  4808. if (((confMgr.SysConfigParams.DisableFrontCam)&&(markParam.MarkType == MarkCam.尺寸检测Mark))||
  4809. ((confMgr.SysConfigParams.DisableBackCam) && (markParam.MarkType == MarkCam.缺陷检测Mark)))
  4810. {
  4811. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4812. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4813. break;
  4814. }
  4815. if ((!SizeEnable)&& (markParam.MarkType == MarkCam.尺寸检测Mark))
  4816. {
  4817. Log($"{stepIndex + 1}-{processName}", $"尺寸检测功能禁用,忽略此步骤!");
  4818. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"尺寸检测功能禁用,忽略此步骤!", 0, false));
  4819. break;
  4820. }
  4821. if ((!DefectEnable) && (markParam.MarkType == MarkCam.缺陷检测Mark))
  4822. {
  4823. Log($"{stepIndex + 1}-{processName}", $"缺陷检测功能禁用,忽略此步骤!");
  4824. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"缺陷检测功能禁用,忽略此步骤!", 0, false));
  4825. break;
  4826. }
  4827. //测试4个mark
  4828. TestCnt = markParam.MarkCnt;
  4829. //判断是否需要使用双控
  4830. if (!WaitGetStartSig())
  4831. {
  4832. return stepIndex;
  4833. }
  4834. //获取之后需计算的手选点位
  4835. //Y轴方向PT值检测
  4836. //线宽正面
  4837. //反面检测
  4838. //X轴方向PT值检测
  4839. //主栅连接线检测
  4840. //主栅宽度检测
  4841. //主栅间距
  4842. //细栅间距检测
  4843. //背极宽度
  4844. List<double> posList = new List<double>();
  4845. double[] posArray = null;
  4846. //string[] pointType = new string[17] { "Y轴方向PT值检测" , "线宽正面" , "反面检测" ,
  4847. //"X轴方向PT值检测","主栅连接线检测","主栅宽度检测","主栅间距","细栅间距检测","背极宽度",
  4848. //"主栅长度检测","Mark点横向间距","Mark点竖向间距","鱼叉口长","鱼叉口宽","鱼叉口间距",
  4849. //"蜈蚣角长", "蜈蚣角宽"};
  4850. string[] pointType = testLabels.ToArray();
  4851. int[] adaqter = new int[pointType.Length];
  4852. if (markParam.AutoMark)
  4853. {
  4854. for (int i = 0; i < pointType.Length; i++)
  4855. {
  4856. List<TestDefectPoints> t1 = model.TestDefectPointsList.Where(q => q.PointCode == pointType[i]).ToList();
  4857. if (t1.Count > 0)
  4858. {
  4859. if (pointType[i] == "Y轴方向PT值检测" || pointType[i] == "X轴方向PT值检测")
  4860. adaqter[i] = t1.Count;
  4861. else
  4862. adaqter[i] = t1.Count * 2;
  4863. //添加点位
  4864. for (int j = 0; j < t1.Count; j++)
  4865. {
  4866. if (t1[j].PointCode == "Y轴方向PT值检测")
  4867. posList.Add(t1[j].X);
  4868. else if (t1[j].PointCode == "X轴方向PT值检测")
  4869. posList.Add(t1[j].Y);
  4870. else
  4871. {
  4872. posList.Add(t1[j].X);
  4873. posList.Add(t1[j].Y);
  4874. }
  4875. }
  4876. }
  4877. }
  4878. }
  4879. else
  4880. {
  4881. ;
  4882. }
  4883. CurrAdaqter = adaqter;
  4884. if (posList.Count >0)
  4885. { posArray = posList.ToArray(); }
  4886. //对应运动轴
  4887. List<int> AxisIndexList = new List<int>();
  4888. if (markParam.MarkType == MarkCam.尺寸检测Mark)
  4889. {
  4890. AxisIndexList.Add(AxisX1);
  4891. AxisIndexList.Add(AxisY);
  4892. }
  4893. else
  4894. {
  4895. AxisIndexList.Add(AxisX2);
  4896. AxisIndexList.Add(AxisY);
  4897. }
  4898. //图纸判断
  4899. string typrstr = markParam.MarkType == MarkCam.尺寸检测Mark ? "尺寸检测Mark" : "缺陷检测Mark";
  4900. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  4901. Log($"{stepIndex + 1}-{processName}", $"Mark检测,Mark类型:{typrstr},{model.AttachmentList.Count}|{(attachmentFile == null ? "null" : attachmentFile.NameTimestamp + attachmentFile.ExtendName)}");
  4902. if (attachmentFile != null)
  4903. {
  4904. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  4905. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName))
  4906. gbxBmpPath = "";
  4907. }
  4908. if (gbxBmpPath == "")
  4909. {
  4910. Log($"{stepIndex + 1}-{processName}", $"Mark检测,Mark类型:{typrstr},图纸不存在!", WarningEnum.High);
  4911. return stepIndex;
  4912. }
  4913. if (this.CurrPoinntCount == 0) //第一点开始
  4914. {
  4915. //传图获取Mark位置,图片大小确定是哪个相机
  4916. HObject markImg;
  4917. string backPath = confMgr.MarkPicPath + (markParam.MarkType == MarkCam.尺寸检测Mark? "\\3333_尺寸.bmp" : "\\3333_缺陷.bmp");
  4918. HOperatorSet.ReadImage(out markImg, backPath);
  4919. OnAutoRuning(new RunEventArgs(stepIndex, "Mark寻找", new List<double>(), 0, 0, 0, 1, false));
  4920. bool isGetMarkPos = GetMarkPoints(true,this.CurrPoinntCount, model.StepInfo.Name,
  4921. stepIndex, processName, markParam.MarkType, markParam.EngineName, markImg.Clone(), gbxBmpPath, adaqter, posArray, false);
  4922. if(!isGetMarkPos)
  4923. {
  4924. //自动获取mark失败
  4925. Log($"{stepIndex + 1}-{processName}", $"Mark位置获取等待超时!", WarningEnum.High);
  4926. return stepIndex;
  4927. }
  4928. }
  4929. //根据mark寻找trg
  4930. //判断有无tag
  4931. if (order.SizeTagDataList == null)
  4932. {
  4933. Log($"{stepIndex + 1}-{processName}", $"Mark数据提供者Tag为空!", WarningEnum.High);
  4934. return stepIndex;
  4935. }
  4936. //tag
  4937. string MarkTag = "";
  4938. if (markParam.MarkType == MarkCam.尺寸检测Mark)
  4939. MarkTag = "F_Mark_" + stepIndex;
  4940. else
  4941. MarkTag = "B_Mark_" + stepIndex;
  4942. //用最新的last
  4943. var sizeTagObj = order.SizeTagDataList.LastOrDefault(m => m.SizeTag == MarkTag);
  4944. if (sizeTagObj == null)
  4945. {
  4946. Log($"{stepIndex + 1}-{processName}", $"未找到自动获取的Mark数据!", WarningEnum.High);
  4947. return stepIndex;
  4948. }
  4949. string[] posePT = sizeTagObj.posePT.Split(',');
  4950. if (posePT.Length < this.CurrPoinntCount * 2 + 2)
  4951. {
  4952. Log($"{stepIndex + 1}-{processName}",
  4953. $"MarkTag对应消费索引:{this.CurrPoinntCount * 2},Axis数量:{2} 超出postPT:{sizeTagObj.posePT} 范围!", WarningEnum.High);
  4954. return stepIndex;
  4955. }
  4956. //交换点位顺序1-2-3-4 =》 1-2-4-3
  4957. string tempPosStr = posePT[4];
  4958. posePT[4] = posePT[6];
  4959. posePT[6] = tempPosStr;
  4960. tempPosStr = posePT[5];
  4961. posePT[5] = posePT[7];
  4962. posePT[7] = tempPosStr;
  4963. //轴运动
  4964. double[] TagPPUValue = new double[AxisIndexList.Count];
  4965. for (int i = 0; i < AxisIndexList.Count; i++)
  4966. TagPPUValue[i] = double.Parse(posePT[this.CurrPoinntCount * 2 + i]);
  4967. for (int i = 0; i < TagPPUValue.Length; i++)
  4968. {
  4969. if (axisDev.CheckDone(AxisIndexList[i], 60) != 0)
  4970. {
  4971. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}到位失败!", WarningEnum.High);
  4972. return stepIndex;
  4973. }
  4974. VelocityCurveParams vel = new VelocityCurveParams(markParam.Acc, markParam.Dec, markParam.VelLow, markParam.VelHigh, MotionST, GetMMtoPlus((AxisName)AxisIndexList[i]));
  4975. int iret = 0;
  4976. iret = axisDev.MoveAbsValue(AxisIndexList[i], vel, TagPPUValue[i]);
  4977. if (iret != 0)
  4978. {
  4979. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}运动失败!", WarningEnum.High);
  4980. return stepIndex;
  4981. }
  4982. }
  4983. if (sizeTagObj.ConsumeStepIndex == null)
  4984. sizeTagObj.ConsumeStepIndex = "";
  4985. sizeTagObj.ConsumeStepIndex += $"{stepIndex + 1}-{this.CurrPoinntCount}, ";//消费工序ID
  4986. //多轴同时运行后强制等待各轴完成
  4987. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  4988. if (!WaitAxisDone(AxisIndexList))
  4989. {
  4990. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  4991. return stepIndex;
  4992. }
  4993. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  4994. Thread.Sleep(markParam.WaitTime);
  4995. //自动聚焦?
  4996. if (markParam.MarkType == MarkCam.尺寸检测Mark)
  4997. {
  4998. CamDevFront.SetExposure(markParam.ExposureTime);
  4999. CamDevFront.SetGain(markParam.Gain);
  5000. }
  5001. if ((this.CurrPoinntCount == 0)&&(IsAutoFocus)&& (markParam.MarkType == MarkCam.尺寸检测Mark))
  5002. {
  5003. Log($"{stepIndex + 1}-{processName}", $"自动聚焦...");
  5004. if(!AutoFocus(FocusStep, DirStep, DirWaitTime, FocusTimeOut))
  5005. {
  5006. Log($"{stepIndex + 1}-{processName}", $"自动聚焦失败!", WarningEnum.High);
  5007. return stepIndex;
  5008. }
  5009. Log($"{stepIndex + 1}-{processName}", $"自动聚焦完成");
  5010. }
  5011. //拍照处理
  5012. HObject DefLastImg = new HObject(); //缺陷左上角使用
  5013. Log($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  5014. if (markParam.MarkType == MarkCam.尺寸检测Mark)
  5015. {
  5016. //CamDevFront.SetExposure(markParam.ExposureTime);
  5017. //CamDevFront.SetGain(markParam.Gain);
  5018. Log($"{stepIndex + 1}-{processName}", $"相机参数设置完成。");
  5019. for (int i = 0; i < snapCnt; i++)
  5020. {
  5021. DateTime dt0 = DateTime.Now;
  5022. CamDevFront.ClearImageQueue();
  5023. Acquisition acq0 = CamDevFront.Snap(1, 5000);
  5024. if (acq0.GrabStatus != "GrabPass")
  5025. {
  5026. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片失败{i}!", WarningEnum.High);
  5027. if(i < snapCnt -1)
  5028. {
  5029. Thread.Sleep(100);
  5030. continue;
  5031. }
  5032. else
  5033. return stepIndex;
  5034. }
  5035. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片完成{i}[" + (DateTime.Now - dt0).Milliseconds.ToString() + "ms]");
  5036. //显示
  5037. OnAutoRuning(new RunEventArgs(0, acq0.Image));
  5038. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  5039. acq0.Image.Clone(),
  5040. GetAxisPosValueMM((int)AxisName.Axis0),
  5041. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  5042. Log($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列," +
  5043. $"X:{GetAxisPosValueMM((int)AxisName.Axis0)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  5044. $"数量: {scannerCBmpQueue.Count}");
  5045. break;
  5046. }
  5047. }
  5048. else
  5049. {
  5050. CamDevBack.SetExposure(markParam.ExposureTime);
  5051. CamDevBack.SetGain(markParam.Gain);
  5052. for (int snapi = 0; snapi < snapCnt; snapi++)
  5053. {
  5054. DateTime dt = DateTime.Now;
  5055. CamDevBack.ClearImageQueue();
  5056. Acquisition acq = CamDevBack.Snap(1, 5000);
  5057. if (acq.GrabStatus != "GrabPass")
  5058. {
  5059. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片失败{snapi}!", WarningEnum.High);
  5060. if(snapi <snapCnt -1)
  5061. {
  5062. Thread.Sleep(100);
  5063. continue;
  5064. }
  5065. else
  5066. return stepIndex;
  5067. }
  5068. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片完成{snapi}[" + (DateTime.Now - dt).Milliseconds.ToString() + "ms]");
  5069. //显示
  5070. OnAutoRuning(new RunEventArgs(1, acq.Image));
  5071. //----缺陷队列
  5072. DefLastImg = acq.Image.Clone();
  5073. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  5074. acq.Image.Clone(),
  5075. GetAxisPosValueMM((int)AxisName.Axis1),
  5076. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  5077. Log($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列," +
  5078. $"X:{GetAxisPosValueMM((int)AxisName.Axis1)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  5079. $"数量: {scannerCBmpQueue.Count}");
  5080. break;
  5081. }
  5082. }
  5083. //mark计算
  5084. bool tRet = GetMarkPoints(false, this.CurrPoinntCount, model.StepInfo.Name,
  5085. stepIndex, processName, markParam.MarkType, markParam.EngineName,
  5086. null, gbxBmpPath, adaqter, posArray, (this.CurrPoinntCount + 1) == TestCnt?false:true);
  5087. if (!tRet)
  5088. {
  5089. //自动获取mark失败
  5090. Log($"{stepIndex + 1}-{processName}", $"Mark位置获取等待超时!", WarningEnum.High);
  5091. return stepIndex;
  5092. }
  5093. //最后判断
  5094. if((this.CurrPoinntCount + 1) == TestCnt)
  5095. {
  5096. if(markParam.MarkType == MarkCam.缺陷检测Mark)
  5097. {
  5098. //缺陷获取左上角位置
  5099. bool isGetMarkPos = GetMarkPoints(true, this.CurrPoinntCount, model.StepInfo.Name,
  5100. stepIndex, processName, markParam.MarkType, markParam.EngineName, DefLastImg.Clone(), gbxBmpPath, adaqter, posArray, false);
  5101. if (!isGetMarkPos)
  5102. {
  5103. //自动获取mark失败
  5104. Log($"{stepIndex + 1}-{processName}", $"左上角位置获取等待超时!", WarningEnum.High);
  5105. return stepIndex;
  5106. }
  5107. }
  5108. OnAutoRuning(new RunEventArgs(stepIndex, "Mark寻找", new List<double>(), 0, 0, 0, tRet?2:3, false));
  5109. }
  5110. #endregion
  5111. break;
  5112. case "PointTest":
  5113. #region 尺寸选点测试
  5114. PointTestProp testParam = JsonConvert.DeserializeObject<PointTestProp>(jsonParams);
  5115. var SizeItem = confMgr.SizeItemParamsList.Find(x => x.Name == testParam.TestType);
  5116. var findindex = confMgr.SizeItemParamsList.FindIndex(x => x.Name == testParam.TestType);
  5117. if (confMgr.SysConfigParams.DisableFrontCam)
  5118. {
  5119. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  5120. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  5121. break;
  5122. }
  5123. if (!SizeEnable)
  5124. {
  5125. Log($"{stepIndex + 1}-{processName}", $"尺寸检测功能禁用,忽略此步骤!");
  5126. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"尺寸检测功能禁用,忽略此步骤!", 0, false));
  5127. break;
  5128. }
  5129. //对应运动轴
  5130. List<int> PAxisIndexList = new List<int>();
  5131. PAxisIndexList.Add(AxisX1);
  5132. PAxisIndexList.Add(AxisY);
  5133. double[] TestPosTagPPUValue = new double[PAxisIndexList.Count * 2];
  5134. TestCnt = 0;
  5135. string[] TestPos = new string[1];
  5136. //图纸
  5137. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  5138. Log($"{stepIndex + 1}-{processName}", $"比对图像,{model.AttachmentList.Count}|{(attachmentFile == null ? "null" : attachmentFile.NameTimestamp + attachmentFile.ExtendName)}");
  5139. //自动点位数计算
  5140. if (attachmentFile != null)
  5141. {
  5142. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  5143. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName))
  5144. gbxBmpPath = "";
  5145. }
  5146. //图纸判断
  5147. if (gbxBmpPath == "")
  5148. {
  5149. Log($"{stepIndex + 1}-{processName}", $"比对图像,图纸不存在!", WarningEnum.High);
  5150. return stepIndex;
  5151. }
  5152. //是否使用手动点位
  5153. if (!testParam.AutoMark)
  5154. {
  5155. //手动点位数计算
  5156. CurrAdaqter = new int[testLabels.Count];
  5157. if(findindex >=0 )
  5158. CurrAdaqter[findindex] = testParam.PointCnt;
  5159. else
  5160. {
  5161. Log($"{stepIndex + 1}-{processName}", $"测试项不在列表!", WarningEnum.High);
  5162. return stepIndex;
  5163. }
  5164. }
  5165. //自动寻点
  5166. if ((testParam.AutoMark)|| (testParam.DefPos))
  5167. {
  5168. //判断有无tag
  5169. if (order.SizeTagDataList == null)
  5170. {
  5171. Log($"{stepIndex + 1}-{processName}", $"点位数据提供者Tag为空!", WarningEnum.High);
  5172. return stepIndex;
  5173. }
  5174. //tag
  5175. string TestPosTag = "F_Pos";
  5176. //用最新的last
  5177. var TestPosTagObj = order.SizeTagDataList.LastOrDefault(m => m.SizeTag == TestPosTag);
  5178. if (TestPosTagObj == null)
  5179. {
  5180. Log($"{stepIndex + 1}-{processName}", $"未找到自动获取的测试点位数据!", WarningEnum.High);
  5181. return stepIndex;
  5182. }
  5183. TestPos = TestPosTagObj.posePT.Split(',');
  5184. if ((testParam.DefPos) &&(TestPos.Length < 38))
  5185. {
  5186. Log($"{stepIndex + 1}-{processName}",
  5187. $"自动获取的默认测试点位数据范围错误:{TestPos.Length}!", WarningEnum.High);
  5188. return stepIndex;
  5189. }
  5190. }
  5191. else
  5192. {
  5193. TestPos = new string[testParam.Points.Count * 2 * SizeItem.PointCnt];
  5194. //if (SizeItem.PointCnt == 2)
  5195. // TestPos = new string[testParam.Points.Count * 4];
  5196. //else
  5197. // TestPos = new string[testParam.Points.Count * 2];
  5198. for (int i = 0; i < testParam.Points.Count; i++)
  5199. {
  5200. TestPos[2 * i] = testParam.Points[i].X.ToString();
  5201. TestPos[2 * i + 1] = testParam.Points[i].Y.ToString();
  5202. }
  5203. }
  5204. int posIndex = this.CurrPoinntCount;
  5205. //手动顺寻
  5206. if( (!testParam.SelectPoint)&&(testParam.Indexs.Count >= testParam.PointCnt))
  5207. {
  5208. posIndex = testParam.Indexs[this.CurrPoinntCount];
  5209. }
  5210. else if (!testParam.SelectPoint)
  5211. {
  5212. Log($"{stepIndex + 1}-{processName}",
  5213. $"手动测试点位顺序范围错误:{testParam.Indexs.Count}!", WarningEnum.High);
  5214. return stepIndex;
  5215. }
  5216. //判断是否一点完成
  5217. bool IsOverDef = true;
  5218. //是否使用点位判断
  5219. if (testParam.DefPos)
  5220. {
  5221. //使用默认点位测试
  5222. if(this.CurrPoinntCount == 0)
  5223. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"默认位置检测开始...", null, 0, 0, 0, 1, false));
  5224. switch (testParam.TestType) {
  5225. case "Y轴方向PT值检测":
  5226. IsOverDef = false;
  5227. TestCnt = testParam.PointCnt;
  5228. if (testParam.PointCnt > 5 )
  5229. {
  5230. Log($"{stepIndex + 1}-{processName}", $"Y轴方向PT值检测参数,默认只支持5点以内!", WarningEnum.High);
  5231. return stepIndex;
  5232. }
  5233. //走位计算
  5234. TestPosTagPPUValue[0] = double.Parse(TestPos[2 * posIndex]);
  5235. TestPosTagPPUValue[1] = double.Parse(TestPos[2 * posIndex + 1]);
  5236. TestPosTagPPUValue[2] = double.Parse(TestPos[2 * posIndex + 10]);
  5237. TestPosTagPPUValue[3] = double.Parse(TestPos[2 * posIndex + 11]);
  5238. break;
  5239. case "线宽正面":
  5240. TestCnt = testParam.PointCnt;
  5241. if (TestCnt > 9)
  5242. {
  5243. Log($"{stepIndex + 1}-{processName}", $"线宽正面参数,默认只支持9点以内!", WarningEnum.High);
  5244. return stepIndex;
  5245. }
  5246. //走位计算
  5247. TestPosTagPPUValue[0] = double.Parse(TestPos[20 + 2 * posIndex]);
  5248. TestPosTagPPUValue[1] = double.Parse(TestPos[20 + 2 * posIndex + 1]);
  5249. break;
  5250. default:
  5251. Log($"{stepIndex + 1}-{processName}", $"参数不支持!", WarningEnum.High);
  5252. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"参数不支持!", 4, false));
  5253. return stepIndex;
  5254. }
  5255. }
  5256. else
  5257. {
  5258. if (this.CurrPoinntCount == 0)
  5259. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"特定位置检测开始...", null, 0, 0, 0, 1, false));
  5260. /******************key
  5261. * Y轴方向PT值检测
  5262. 线宽正面
  5263. 反面检测
  5264. X轴方向PT值检测
  5265. 主栅连接线检测
  5266. 主栅宽度检测
  5267. 主栅间距
  5268. 细栅间距检测
  5269. 背极宽度
  5270. ******************/
  5271. List<TestDefectPoints> t = new List<TestDefectPoints>();
  5272. switch (testParam.TestType)
  5273. {
  5274. case "Y轴方向PT值检测":
  5275. IsOverDef = false;
  5276. TestCnt = testParam.PointCnt;
  5277. t = model.TestDefectPointsList.Where(q => q.PointCode == "Y轴方向PT值检测").ToList();
  5278. if (testParam.AutoMark)
  5279. {
  5280. if (testParam.PointCnt > t.Count)
  5281. {
  5282. Log($"{stepIndex + 1}-{processName}", $"Y轴方向PT值检测参数,点数大于产品配置点数!", WarningEnum.High);
  5283. return stepIndex;
  5284. }
  5285. }
  5286. //走位计算
  5287. TestPosTagPPUValue[0] = double.Parse(TestPos[2 * posIndex]);
  5288. TestPosTagPPUValue[1] = double.Parse(TestPos[2 * posIndex + 1]);
  5289. TestPosTagPPUValue[2] = double.Parse(TestPos[2 * posIndex + this.CurrAdaqter[0] * 2]);
  5290. TestPosTagPPUValue[3] = double.Parse(TestPos[2 * posIndex + this.CurrAdaqter[0] * 2 + 1]);
  5291. break;
  5292. case "X轴方向PT值检测":
  5293. IsOverDef = false;
  5294. TestCnt = testParam.PointCnt;
  5295. t = model.TestDefectPointsList.Where(q => q.PointCode == "X轴方向PT值检测").ToList();
  5296. if (testParam.AutoMark)
  5297. if (testParam.PointCnt > t.Count)
  5298. {
  5299. Log($"{stepIndex + 1}-{processName}", $"X轴方向PT值检测参数,点数大于产品配置点数!", WarningEnum.High);
  5300. return stepIndex;
  5301. }
  5302. //走位计算
  5303. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1] + this.CurrAdaqter[2] + 2 * posIndex]);
  5304. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1] + this.CurrAdaqter[2] + 2 * posIndex + 1]);
  5305. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1] + this.CurrAdaqter[2] + 2 * posIndex + this.CurrAdaqter[3] * 2]);
  5306. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1] + this.CurrAdaqter[2] + 2 * posIndex + this.CurrAdaqter[3] * 2 + 1]);
  5307. break;
  5308. default:
  5309. //判断是否两点测试
  5310. IsOverDef = SizeItem.PointCnt > 1 ? false : true;
  5311. TestCnt = testParam.PointCnt;
  5312. //获取对应的测试点数
  5313. t = model.TestDefectPointsList.Where(q => q.PointCode == SizeItem.Name).ToList();
  5314. if (testParam.AutoMark)
  5315. if (testParam.PointCnt > t.Count)
  5316. {
  5317. Log($"{stepIndex + 1}-{processName}", $"{SizeItem.Name}参数,点数大于产品配置点数!", WarningEnum.High);
  5318. return stepIndex;
  5319. }
  5320. //走位计算
  5321. int teatposIndex = 0;
  5322. for (int i = 0; i < confMgr.SizeItemParamsList.Count; i++)
  5323. {
  5324. if (i == 0)
  5325. teatposIndex += this.CurrAdaqter[0] * 4 * (findindex > i ? 1 : 0);
  5326. else if (i == 3)
  5327. teatposIndex += this.CurrAdaqter[3] * 4 * (findindex > i ? 1 : 0);
  5328. else
  5329. teatposIndex += this.CurrAdaqter[i] * (findindex > i ? 1 : 0);
  5330. }
  5331. TestPosTagPPUValue[0] = double.Parse(TestPos[teatposIndex + 2 * SizeItem.PointCnt * posIndex]);
  5332. TestPosTagPPUValue[1] = double.Parse(TestPos[teatposIndex + 2 * SizeItem.PointCnt * posIndex + 1]);
  5333. if (SizeItem.PointCnt > 1)
  5334. {
  5335. TestPosTagPPUValue[2] = double.Parse(TestPos[teatposIndex + 2 * SizeItem.PointCnt * posIndex + 2]);
  5336. TestPosTagPPUValue[3] = double.Parse(TestPos[teatposIndex + 2 * SizeItem.PointCnt * posIndex + 3]);
  5337. }
  5338. //Log($"{stepIndex + 1}-{processName}", $"参数不支持!", WarningEnum.High);
  5339. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"参数不支持!", 4, false));
  5340. //return stepIndex;
  5341. break;
  5342. }
  5343. }
  5344. //PT检测需要两点
  5345. for (int i = 0; i < 2; i++)
  5346. {
  5347. //轴运动
  5348. for (int j = 0; j < 2; j++)
  5349. {
  5350. if (axisDev.CheckDone(PAxisIndexList[j], 60) != 0)
  5351. {
  5352. Log($"{stepIndex + 1}-{processName}", $"轴{PAxisIndexList[j]}到位失败!", WarningEnum.High);
  5353. return stepIndex;
  5354. }
  5355. VelocityCurveParams vel = new VelocityCurveParams(testParam.Acc, testParam.Dec, testParam.VelLow, testParam.VelHigh, MotionST, GetMMtoPlus((AxisName)PAxisIndexList[i]));
  5356. int iret = 0;
  5357. iret = axisDev.MoveAbsValue(PAxisIndexList[j], vel, TestPosTagPPUValue[j + i *2]);
  5358. if (iret != 0)
  5359. {
  5360. Log($"{stepIndex + 1}-{processName}", $"轴{PAxisIndexList[j]}运动失败!", WarningEnum.High);
  5361. return stepIndex;
  5362. }
  5363. }
  5364. //多轴同时运行后强制等待各轴完成
  5365. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  5366. if (!WaitAxisDone(PAxisIndexList))
  5367. {
  5368. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  5369. return stepIndex;
  5370. }
  5371. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  5372. Thread.Sleep(testParam.WaitTime);
  5373. camDevFront.SetExposure(testParam.ExposureTime);
  5374. camDevFront.SetGain(testParam.Gain);
  5375. //自动聚焦?
  5376. if ((this.CurrPoinntCount == 0) && (IsAutoFocus)&& (i == 0))//第一次拍照才聚焦
  5377. {
  5378. Log($"{stepIndex + 1}-{processName}", $"自动聚焦...");
  5379. if (!AutoFocus(FocusStep, DirStep, DirWaitTime, FocusTimeOut))
  5380. {
  5381. Log($"{stepIndex + 1}-{processName}", $"自动聚焦失败!", WarningEnum.High);
  5382. return stepIndex;
  5383. }
  5384. Log($"{stepIndex + 1}-{processName}", $"自动聚焦完成");
  5385. }
  5386. else if (testParam.AutoFocus)//每次都聚焦
  5387. {
  5388. Log($"{stepIndex + 1}-{processName}", $"拍照前自动聚焦...");
  5389. if (!AutoFocus(testParam.FocusStep, testParam.DirStep, testParam.WaitDoneTime, testParam.TimeOut))
  5390. {
  5391. Log($"{stepIndex + 1}-{processName}", $"拍照前自动聚焦失败!", WarningEnum.High);
  5392. return stepIndex;
  5393. }
  5394. Log($"{stepIndex + 1}-{processName}", $"拍照前自动聚焦完成");
  5395. }
  5396. //拍照
  5397. Log($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  5398. for (int snapi = 0; snapi < snapCnt; snapi++)
  5399. {
  5400. DateTime test_dt = DateTime.Now;
  5401. camDevFront.ClearImageQueue();
  5402. Acquisition test_acq = camDevFront.Snap(1, 5000);
  5403. if (test_acq.GrabStatus != "GrabPass")
  5404. {
  5405. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片失败{snapi}!", WarningEnum.High);
  5406. if(snapi < snapCnt -1)
  5407. {
  5408. Thread.Sleep(100);
  5409. continue;
  5410. }
  5411. else
  5412. return stepIndex;
  5413. }
  5414. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片完成{snapi}[" + (DateTime.Now - test_dt).Milliseconds.ToString() + "ms]");
  5415. //显示
  5416. OnAutoRuning(new RunEventArgs(0, test_acq.Image));
  5417. //----处理队列
  5418. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  5419. test_acq.Image.Clone(),
  5420. GetAxisPosValueMM((int)AxisName.Axis0),
  5421. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  5422. Log($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列," +
  5423. $"X:{GetAxisPosValueMM((int)AxisName.Axis0)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  5424. $"数量: {scannerCBmpQueue.Count}");
  5425. break;
  5426. }
  5427. //处理
  5428. if (!PointTestDef(stepIndex, processName, testParam.EngineName, gbxBmpPath, false, model, testParam, IsOverDef, SizeItem))
  5429. {
  5430. Log($"{stepIndex + 1}-{processName}", $"单点测试图像,比对任务失败!", WarningEnum.High);
  5431. return stepIndex;
  5432. }
  5433. //需要二次点位的在循环,否则直接跳出
  5434. if (!IsOverDef)
  5435. IsOverDef = true;
  5436. else
  5437. break;
  5438. }
  5439. #endregion
  5440. break;
  5441. case "SizeAndDefect":
  5442. #region 缺陷
  5443. SizeDefectProp defectParam = JsonConvert.DeserializeObject<SizeDefectProp>(jsonParams);
  5444. if (confMgr.SysConfigParams.DisableBackCam)
  5445. {
  5446. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  5447. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, true));
  5448. break;
  5449. }
  5450. if (!DefectEnable)
  5451. {
  5452. Log($"{stepIndex + 1}-{processName}", $"缺陷检测功能禁用,忽略此步骤!");
  5453. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"缺陷检测功能禁用,忽略此步骤!", 0, true));
  5454. break;
  5455. }
  5456. //对应运动轴
  5457. List<int> DAxisIndexList = new List<int>();
  5458. DAxisIndexList.Add(AxisX2);
  5459. DAxisIndexList.Add(AxisY);
  5460. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"比对和缺陷检测开始...", 1, true));
  5461. //获取首点和长宽
  5462. if (this.CurrPoinntCount == 0)
  5463. {
  5464. //添加打印信息
  5465. AddDefectPrintInfo(defectParam);
  5466. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "比对和缺陷检测开始...", null, 0, 0, 0, 1, true));
  5467. double Pdt_Width = 0;
  5468. double Pdt_Height = 0;
  5469. //根据mark寻找trg
  5470. //判断有无tag
  5471. if (order.SizeTagDataList == null)
  5472. {
  5473. Log($"{stepIndex + 1}-{processName}", $"Mark数据提供者Tag为空!", WarningEnum.High);
  5474. return stepIndex;
  5475. }
  5476. //tag
  5477. string LeftPosTag = "B_Pos";
  5478. //用最新的last
  5479. var LeftPosTagObj = order.SizeTagDataList.LastOrDefault(m => m.SizeTag == LeftPosTag);
  5480. if (LeftPosTagObj == null)
  5481. {
  5482. Log($"{stepIndex + 1}-{processName}", $"未找到自动获取的左上角和产品大小数据!", WarningEnum.High);
  5483. return stepIndex;
  5484. }
  5485. string[] PosAndSize = LeftPosTagObj.posePT.Split(',');
  5486. if (PosAndSize.Length < 6)
  5487. {
  5488. Log($"{stepIndex + 1}-{processName}",
  5489. $"缺陷检测首点对应消费索引:{this.CurrPoinntCount * 2},Axis数量:{2} 超出postPT:{LeftPosTagObj.posePT} 范围!", WarningEnum.High);
  5490. return stepIndex;
  5491. }
  5492. //获取首点,计算步进
  5493. //Left_X = double.Parse(PosAndSize[0]) + confMgr.SysConfigParams.DefectCamViewX; //需要偏移
  5494. //Left_Y = double.Parse(PosAndSize[1]);
  5495. Left_X = double.Parse(PosAndSize[4]);
  5496. Left_Y = double.Parse(PosAndSize[5]);
  5497. Pdt_Width = double.Parse(PosAndSize[2]);
  5498. Pdt_Height = double.Parse(PosAndSize[3]);
  5499. //X_For = (int)(Pdt_Width / confMgr.SysConfigParams.DefectCamViewX) + 1;
  5500. //Y_For = (int)(Pdt_Height / confMgr.SysConfigParams.DefectCamViewY) + 1;
  5501. //左上角加入视野大小10%的补偿
  5502. double temp_dis = confMgr.SysConfigParams.DefectCamViewX * confMgr.SysConfigParams.X_per;
  5503. Left_X = double.Parse(PosAndSize[4]) - temp_dis;
  5504. temp_dis = confMgr.SysConfigParams.DefectCamViewY * confMgr.SysConfigParams.Y_per;
  5505. Left_Y = double.Parse(PosAndSize[5]) + temp_dis;
  5506. //double temp_dis = ((X_For * confMgr.SysConfigParams.DefectCamViewX - Pdt_Width) / 2);
  5507. //if (temp_dis < (confMgr.SysConfigParams.DefectCamViewX / 5))
  5508. //{
  5509. // X_For = X_For + 1;
  5510. // temp_dis = ((X_For * confMgr.SysConfigParams.DefectCamViewX - Pdt_Width) / 2);
  5511. //}
  5512. //Left_X = double.Parse(PosAndSize[4]) - temp_dis;
  5513. //temp_dis = ((Y_For * confMgr.SysConfigParams.DefectCamViewY - Pdt_Height) / 2);
  5514. //if (temp_dis < (confMgr.SysConfigParams.DefectCamViewY / 5))
  5515. //{
  5516. // Y_For++;
  5517. // temp_dis = ((Y_For * confMgr.SysConfigParams.DefectCamViewY - Pdt_Height) / 2);
  5518. //}
  5519. //Left_Y = double.Parse(PosAndSize[5]) + temp_dis;
  5520. if ((Pdt_Width + (confMgr.SysConfigParams.DefectCamViewX * confMgr.SysConfigParams.X_per))
  5521. % confMgr.SysConfigParams.DefectCamViewX > 0)
  5522. X_For = (int)((Pdt_Width + (confMgr.SysConfigParams.DefectCamViewX * confMgr.SysConfigParams.X_per) )/ confMgr.SysConfigParams.DefectCamViewX) + 1;
  5523. else
  5524. X_For = (int)((Pdt_Width + (confMgr.SysConfigParams.DefectCamViewX * confMgr.SysConfigParams.X_per)) / confMgr.SysConfigParams.DefectCamViewX);
  5525. if ((Pdt_Height + (confMgr.SysConfigParams.DefectCamViewY * confMgr.SysConfigParams.Y_per))
  5526. % confMgr.SysConfigParams.DefectCamViewY > 0)
  5527. Y_For = (int)((Pdt_Height + (confMgr.SysConfigParams.DefectCamViewY * confMgr.SysConfigParams.Y_per)) / confMgr.SysConfigParams.DefectCamViewY) + 1;
  5528. else
  5529. Y_For = (int)((Pdt_Height + (confMgr.SysConfigParams.DefectCamViewY * confMgr.SysConfigParams.Y_per)) / confMgr.SysConfigParams.DefectCamViewY);
  5530. //判断是否使用手动
  5531. if(!defectParam.AutoLeft)
  5532. {
  5533. if (defectParam.LeftPoints.Count > 0)
  5534. {
  5535. Left_X = defectParam.LeftPoints[0].X;
  5536. Left_Y = defectParam.LeftPoints[0].Y;
  5537. }
  5538. else
  5539. {
  5540. Log($"{stepIndex + 1}-{processName}", $"设置左上角为空{defectParam.LeftPoints[0]}!", WarningEnum.High);
  5541. return stepIndex;
  5542. }
  5543. }
  5544. if (!defectParam.AutoStep)
  5545. {
  5546. X_For = defectParam.Xstep;
  5547. Y_For = defectParam.Ystep;
  5548. }
  5549. X_For_Index = 0;
  5550. Y_For_Index = 0;
  5551. ////////////////////
  5552. //X_For = 6;
  5553. //Y_For = 7;
  5554. }
  5555. TestCnt = Y_For * X_For;
  5556. //走位计算
  5557. double[] PosTagPPUValue = new double[DAxisIndexList.Count];
  5558. PosTagPPUValue[0] = Left_X + X_For_Index * confMgr.SysConfigParams.DefectCamViewX;
  5559. PosTagPPUValue[1] = Left_Y - Y_For_Index * confMgr.SysConfigParams.DefectCamViewY;
  5560. //轴运动
  5561. for (int i = 0; i < PosTagPPUValue.Length; i++)
  5562. {
  5563. if (axisDev.CheckDone(DAxisIndexList[i], 60) != 0)
  5564. {
  5565. Log($"{stepIndex + 1}-{processName}", $"轴{DAxisIndexList[i]}到位失败!", WarningEnum.High);
  5566. return stepIndex;
  5567. }
  5568. VelocityCurveParams vel = new VelocityCurveParams(defectParam.Acc, defectParam.Dec, defectParam.VelLow, defectParam.VelHigh, MotionST, GetMMtoPlus((AxisName)DAxisIndexList[i]));
  5569. int iret = 0;
  5570. iret = axisDev.MoveAbsValue(DAxisIndexList[i], vel, PosTagPPUValue[i]);
  5571. if (iret != 0)
  5572. {
  5573. Log($"{stepIndex + 1}-{processName}", $"轴{DAxisIndexList[i]}运动失败!", WarningEnum.High);
  5574. return stepIndex;
  5575. }
  5576. }
  5577. //if (sizeTagObj.ConsumeStepIndex == null)
  5578. // sizeTagObj.ConsumeStepIndex = "";
  5579. //sizeTagObj.ConsumeStepIndex += $"{stepIndex + 1}-{this.CurrPoinntCount}, ";//消费工序ID
  5580. //多轴同时运行后强制等待各轴完成
  5581. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  5582. if (!WaitAxisDone(DAxisIndexList))
  5583. {
  5584. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  5585. return stepIndex;
  5586. }
  5587. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  5588. Thread.Sleep(defectParam.WaitTime);
  5589. //拍照
  5590. Log($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  5591. CamDevBack.SetExposure(defectParam.ExposureTime);
  5592. CamDevBack.SetGain(defectParam.Gain);
  5593. for (int snapi = 0; snapi < snapCnt; snapi++)
  5594. {
  5595. DateTime def_dt = DateTime.Now;
  5596. CamDevBack.ClearImageQueue();
  5597. Acquisition def_acq = CamDevBack.Snap(1, 5000);
  5598. if (def_acq.GrabStatus != "GrabPass")
  5599. {
  5600. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片失败!", WarningEnum.High);
  5601. if(snapi <snapCnt -1)
  5602. {
  5603. Thread.Sleep(100);
  5604. continue;
  5605. }
  5606. else
  5607. return stepIndex;
  5608. }
  5609. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片完成[" + (DateTime.Now - def_dt).Milliseconds.ToString() + "ms]");
  5610. //显示
  5611. OnAutoRuning(new RunEventArgs(1, def_acq.Image));
  5612. //图纸
  5613. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  5614. Log($"{stepIndex + 1}-{processName}", $"比对图像,{model.AttachmentList.Count}|{(attachmentFile == null ? "null" : attachmentFile.NameTimestamp + attachmentFile.ExtendName)}");
  5615. if (attachmentFile != null)
  5616. {
  5617. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  5618. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName))
  5619. gbxBmpPath = "";
  5620. }
  5621. if (gbxBmpPath == "")
  5622. {
  5623. Log($"{stepIndex + 1}-{processName}", $"比对图像,图纸不存在!", WarningEnum.High);
  5624. return stepIndex;
  5625. }
  5626. //----缺陷队列
  5627. if (defectParam.OpenDefect)
  5628. {
  5629. var mat = CamDev.HImageToMat(def_acq.Image);
  5630. scannerGBmpQueue.Enqueue(new scannerGBmpLoc(mat,
  5631. GetAxisPosValueMM((int)AxisName.Axis1),
  5632. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  5633. Log($"{stepIndex + 1}-{processName}", $"缺陷图像队列数量: {scannerGBmpQueue.Count}");
  5634. if (!DefectPicture(stepIndex, processName, defectParam, gbxBmpPath, model, model.StepInfo.Name))
  5635. {
  5636. Log($"{stepIndex + 1}-{processName}", $"缺陷处理,缺陷任务失败!", WarningEnum.High);
  5637. return stepIndex;
  5638. }
  5639. }
  5640. if (defectParam.OpenSize)
  5641. {
  5642. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  5643. def_acq.Image.Clone(),
  5644. GetAxisPosValueMM((int)AxisName.Axis1),
  5645. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  5646. Log($"{stepIndex + 1}-{processName}", $"比对图像队列," +
  5647. $"X:{GetAxisPosValueMM((int)AxisName.Axis1)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  5648. $"数量: {scannerCBmpQueue.Count}");
  5649. //比对处理
  5650. if (!SizeComp(stepIndex, processName, defectParam.EngineName, gbxBmpPath, model.StepInfo.Name, defectParam.AsynRun))
  5651. {
  5652. Log($"{stepIndex + 1}-{processName}", $"比对图像,比对任务失败!", WarningEnum.High);
  5653. return stepIndex;
  5654. }
  5655. }
  5656. break;
  5657. }
  5658. //计算下一步
  5659. if (Y_For_Index % 2 == 0)
  5660. {
  5661. X_For_Index++;
  5662. if (X_For_Index >= X_For)
  5663. {
  5664. Y_For_Index++;
  5665. X_For_Index--;
  5666. }
  5667. }
  5668. else
  5669. {
  5670. X_For_Index--;
  5671. if (X_For_Index < 0)
  5672. {
  5673. Y_For_Index++;
  5674. X_For_Index++;
  5675. }
  5676. }
  5677. if (Y_For_Index >= Y_For)
  5678. {
  5679. Y_For_Index = 0;
  5680. X_For_Index = 0;
  5681. }
  5682. #endregion
  5683. break;
  5684. case "For":
  5685. #region 循环
  5686. long UniqueId = processParam.Value<long>("UniqueId");
  5687. int GotoStepIndex = processParam.Value<int>("GotoStepIndex");//1-n
  5688. int LimitNum = processParam.Value<int>("LimitNum");//1-n
  5689. bool Reset = processParam.Value<bool>("Reset");
  5690. if (GotoStepIndex - 1 == stepIndex)
  5691. {
  5692. Log($"{stepIndex + 1}-{processName}", $"For死循环!!!", WarningEnum.High);
  5693. return stepIndex;
  5694. }
  5695. if (!forLib.dicData.ContainsKey(UniqueId))
  5696. forLib.dicData.Add(UniqueId, 0);
  5697. //
  5698. int Num = forLib.dicData[UniqueId];
  5699. Num++;
  5700. if (Num <= LimitNum)
  5701. {
  5702. if (Num == LimitNum)
  5703. {
  5704. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num}/{LimitNum}]次,循环完成"));
  5705. Log($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次,循环完成。");
  5706. }
  5707. else
  5708. {
  5709. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num}/{LimitNum}]次"));
  5710. Log($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次跳转到步骤[{GotoStepIndex}]...");
  5711. stepIndex = GotoStepIndex - 2;
  5712. }
  5713. forLib.dicData[UniqueId] = Num;
  5714. }
  5715. else
  5716. {
  5717. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"已失效不执行"));
  5718. Log($"{stepIndex + 1}-{processName}", $"本循环已失效不执行!");
  5719. }
  5720. //达到limit重置0
  5721. if (forLib.dicData[UniqueId] >= LimitNum && Reset)
  5722. {
  5723. forLib.dicData[UniqueId] = 0;
  5724. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[0/{LimitNum}]次"));
  5725. Log($"{stepIndex + 1}-{processName}", $"计数器已重置。");
  5726. }
  5727. #endregion
  5728. break;
  5729. default:
  5730. Log($"{stepIndex + 1}-{processName}", $"未知新工序:{processInfo.ProcessCode}", WarningEnum.High);
  5731. return stepIndex;
  5732. }
  5733. #endregion
  5734. }
  5735. }
  5736. else
  5737. {
  5738. if (IsNewStep)
  5739. {
  5740. OnAutoRuning(new RunEventArgs(stepIndex, $"未启用,忽略此步骤!", 0, processInfo.ProcessCode == "SizeAndDefect"));
  5741. }
  5742. }
  5743. //============结束,判断是否自动下料
  5744. if (!IsNewStep)
  5745. {
  5746. #region 老流程结束判断
  5747. if (stepIndex == processList.Count - 1)
  5748. {
  5749. Log("下料", "产品测试完成,移动到下料位");
  5750. bool ret = GotoLoadPos();
  5751. if (!ret)
  5752. {
  5753. Log("下料", "系统电机复位失败", WarningEnum.High);
  5754. }
  5755. if (!RunQG(false))
  5756. {
  5757. Log("下料", "系统IO复位失败", WarningEnum.High);
  5758. }
  5759. Log("结果", "产品测试完成,等待测试结果...");
  5760. //等待缺陷图显示完成
  5761. while (defectBmpNum != defectBmpNumResult)
  5762. Thread.Sleep(100);
  5763. //判断是否合格
  5764. string defectNames = "";
  5765. {
  5766. #region 结果判断
  5767. Log("结果", "结果判断");
  5768. int itemDefectCount;
  5769. bool isGetQua = false;
  5770. for (int enumcnt = 0; enumcnt < confMgr.DefectItemParamsList.Count; enumcnt++)
  5771. {
  5772. isGetQua = false;
  5773. //判断是否是过滤项
  5774. if (model.QualifiedCriterionList != null && model.QualifiedCriterionList.Count > 0)
  5775. {
  5776. foreach (var item in model.QualifiedCriterionList)
  5777. {
  5778. try
  5779. {
  5780. //是过滤
  5781. if (item.DefectCode == confMgr.DefectItemParamsList[enumcnt].Code)
  5782. {
  5783. isGetQua = true;
  5784. itemDefectCount = getDefectCountFromCode(order, item.DefectCode);
  5785. if (item.MaxDefectCount > -1 && itemDefectCount > item.MaxDefectCount)
  5786. {
  5787. order.Qualified = false;
  5788. defectNames += $"{confMgr.DefectItemParamsList[enumcnt].Name}({itemDefectCount}),";
  5789. }
  5790. }
  5791. }
  5792. catch { }
  5793. }
  5794. }
  5795. if (!isGetQua)
  5796. {
  5797. itemDefectCount = getDefectCountFromCode(order, confMgr.DefectItemParamsList[enumcnt].Code);
  5798. if (itemDefectCount > 0)
  5799. {
  5800. order.Qualified = false;
  5801. defectNames += $"{confMgr.DefectItemParamsList[enumcnt].Name}({itemDefectCount}),";
  5802. }
  5803. }
  5804. }
  5805. #endregion
  5806. }
  5807. stopWatch.Stop();
  5808. long timeLen = stopWatch.ElapsedMilliseconds / 1000;
  5809. OnAutoRuning(new RunEventArgs(4, defectNames == "", AllDefectCount, defectNames));
  5810. OnAutoRuning(new RunEventArgs(timeLen));
  5811. //界面显示
  5812. order.TimeLen = timeLen;
  5813. order.DefectCount = AllDefectCount;
  5814. order.Succeed = true;
  5815. order.ModifyUserCode = order.CreateUserCode = userMgr.LoginUser.Code;
  5816. order.Abnormalities = "";//无异常
  5817. order.RepairCode = "";//无修复人员
  5818. //如SN检测已存在,先删除
  5819. var oldSNOrder = OrderService.GetFirst(m => m.SN == order.SN);
  5820. if (oldSNOrder != null)
  5821. {
  5822. Log("删除记录", $"删除上一重复SN检测记录:SN={oldSNOrder.SN}, Date={oldSNOrder.CreateTime}");
  5823. OrderService.DelNav(oldSNOrder);
  5824. }
  5825. if (!OrderService.InsertNav(order))//导航插入
  5826. Log("保存失败", $"保存生产记录失败!", WarningEnum.Low);
  5827. //更新本批次检测数量
  5828. if (!string.IsNullOrWhiteSpace(model.BatchId))
  5829. {
  5830. var expOrder = Expressionable.Create<Order>()
  5831. .And(m => m.ProductId == model.Id)
  5832. .And(m => m.BatchId == model.BatchId)
  5833. .ToExpression();//注意 这一句 不能少
  5834. CurrProductModel.CompleteCount = OrderService.Count(expOrder);
  5835. }
  5836. //以主键为条件更新CompleteCount单列值
  5837. PdtService.Update(it => new Product() { CompleteCount = CurrProductModel.CompleteCount }, it => it.Id == CurrProductModel.Id);
  5838. //记录日产量
  5839. if(confMgr.SetDailyOutputAdd(out DailyOutput))
  5840. {
  5841. OnAutoRuning(new RunEventArgs(timeLen, DailyOutput));
  5842. SendDailyOutput();
  5843. }
  5844. Log("完成", $"用时 {order.TimeLen} 秒");
  5845. _isAuto = false;
  5846. OnAutoRuning(new RunEventArgs(_isAuto));
  5847. //GotoReadyPosAndIO();
  5848. statusMgr.ClearWarning();
  5849. LedReady();
  5850. statusMgr.GotoNormalStandby();
  5851. SendStatus();
  5852. CurrPoinntCount = 0;
  5853. CurrProcessIndex = -1;
  5854. #region MES弃用
  5855. //MES上传
  5856. if (confMgr.SysConfigParams.EnableHttp)
  5857. {
  5858. #if false
  5859. string messtr = GetMesString(confMgr.SysConfigParams.HttpTempPath, model, false);
  5860. Log("MES上传", $"Url:{confMgr.SysConfigParams.HttpUrl}, Date={messtr}");
  5861. string rel = "";
  5862. try
  5863. {
  5864. rel = HttpApi.Post(confMgr.SysConfigParams.HttpUrl, HttpApi.HttpContentType.application_json, messtr);
  5865. Log("MES反馈", $"return:{rel}");
  5866. }
  5867. catch (Exception e)
  5868. {
  5869. Log("MES上传失败", $"失败原因:{e.Message}");
  5870. }
  5871. if (!string.IsNullOrEmpty(rel))
  5872. {
  5873. try
  5874. {
  5875. JObject jo = (JObject)JsonConvert.DeserializeObject(rel);
  5876. if (jo != null)
  5877. {
  5878. if (jo.ContainsKey(confMgr.SysConfigParams.HttpReturnKey) && jo[confMgr.SysConfigParams.HttpReturnKey] != null)
  5879. {
  5880. if (jo[confMgr.SysConfigParams.HttpReturnKey].ToString() == confMgr.SysConfigParams.HttpReturnValue)
  5881. Log("MES上传", $"上传数据成功:{rel}");
  5882. else
  5883. Log("MES上传", $"上传数据失败:{rel}", WarningEnum.Low);
  5884. }
  5885. else
  5886. Log("MES上传", $"上传数据无返回结果:{rel}", WarningEnum.Low);
  5887. }
  5888. else
  5889. {
  5890. Log("MES上传", $"上传数据无反应:{rel}", WarningEnum.Low);
  5891. }
  5892. }
  5893. catch (Exception e)
  5894. {
  5895. Log("MES反馈失败", $"失败原因:{e.Message}", WarningEnum.Low);
  5896. }
  5897. }
  5898. #endif
  5899. }
  5900. #endregion
  5901. #region 打印弃用
  5902. if (confMgr.SysConfigParams.EnableLabelPrint)
  5903. {
  5904. //Log("标签打印", $"打印机:{confMgr.SysConfigParams.LabelPrinterName}, 模板路径={confMgr.SysConfigParams.LabelTempPath}");
  5905. //ret = PrintFileData(PrinterType.Label, confMgr.SysConfigParams.LabelPrinterName,
  5906. // confMgr.SysConfigParams.LabelTempPath, confMgr.SysConfigParams.LabelData, model);
  5907. //if (ret)
  5908. // Log("标签打印", $"打印成功:{confMgr.SysConfigParams.LabelData}");
  5909. //else
  5910. // Log("标签打印", $"打印失败:打印机={confMgr.SysConfigParams.LabelPrinterName}, 模板路径={confMgr.SysConfigParams.LabelTempPath}, 打印数据={confMgr.SysConfigParams.LabelData}", WarningEnum.Low);
  5911. }
  5912. if (confMgr.SysConfigParams.EnableExcelPrint)
  5913. {
  5914. //Log("Excel打印", $"打印机:{confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={confMgr.SysConfigParams.ExcelTempPath}");
  5915. //ret = PrintFileData(PrinterType.Excel, confMgr.SysConfigParams.ExcelPrinterName,
  5916. // confMgr.SysConfigParams.ExcelTempPath, confMgr.SysConfigParams.ExcelData, model);
  5917. //if (ret)
  5918. // Log("Excel打印", $"打印成功:{confMgr.SysConfigParams.ExcelData}");
  5919. //else
  5920. // Log("Excel打印", $"打印失败:打印机={confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={confMgr.SysConfigParams.ExcelTempPath}, 打印数据={confMgr.SysConfigParams.ExcelData}", WarningEnum.Low);
  5921. }
  5922. #endregion
  5923. return -1;
  5924. }
  5925. else //继续
  5926. {
  5927. return ++stepIndex;
  5928. }
  5929. #endregion
  5930. }
  5931. else
  5932. {
  5933. #region 新流程结束判断
  5934. this.CurrPoinntCount++;
  5935. if ((stepIndex == processList.Count - 1)&& (this.CurrPoinntCount >= TestCnt))
  5936. {
  5937. Log("下料", "产品测试完成,移动到下料位");
  5938. bool ret = GotoLoadPos();
  5939. if (!ret)
  5940. {
  5941. Log("下料", "系统电机复位失败", WarningEnum.High);
  5942. }
  5943. if (!RunQG(false))
  5944. {
  5945. Log("下料", "系统IO复位失败", WarningEnum.High);
  5946. }
  5947. Log("结果", "产品测试完成,等待测试结果...");
  5948. //等待比对显示完成
  5949. while (compBmpNum != compBmpIndex)
  5950. Thread.Sleep(100);
  5951. //等待缺陷图显示完成
  5952. while (defectBmpNum != defectBmpNumResult)
  5953. Thread.Sleep(100);
  5954. //判断是否合格
  5955. string defectNames = "";
  5956. if (model.QualifiedCriterionList != null && model.QualifiedCriterionList.Count > 0)
  5957. {
  5958. int itemDefectCount;
  5959. foreach (var item in model.QualifiedCriterionList)
  5960. {
  5961. try
  5962. {
  5963. itemDefectCount = getDefectCountFromCode(order, item.DefectCode);
  5964. var defectItemTemp = confMgr.DefectItemParamsList.Find(x => x.Code == item.DefectCode);
  5965. if (item.MaxDefectCount > -1 && itemDefectCount > item.MaxDefectCount)
  5966. {
  5967. order.Qualified = false;
  5968. defectNames += $"{defectItemTemp.Name}({itemDefectCount}),";
  5969. }
  5970. }
  5971. catch
  5972. { }
  5973. }
  5974. }
  5975. else
  5976. {
  5977. Log("结果", "默认判断");
  5978. int itemDefectCount;
  5979. for (int enumcnt = 0; enumcnt < confMgr.DefectItemParamsList.Count; enumcnt++)
  5980. {
  5981. try
  5982. {
  5983. itemDefectCount = getDefectCountFromCode(order, confMgr.DefectItemParamsList[enumcnt].Code);
  5984. if (itemDefectCount > 0)
  5985. {
  5986. order.Qualified = false;
  5987. defectNames += $"{confMgr.DefectItemParamsList[enumcnt].Name}({itemDefectCount}),";
  5988. }
  5989. }
  5990. catch
  5991. { }
  5992. }
  5993. }
  5994. //移除最后的,
  5995. if(defectNames.Length>0)
  5996. {
  5997. defectNames = defectNames.Remove(defectNames.Length - 1);
  5998. }
  5999. stopWatch.Stop();
  6000. long timeLen = stopWatch.ElapsedMilliseconds / 1000;
  6001. //OnAutoRuning(new RunEventArgs(4, defectNames == "", AllDefectCount, defectNames));
  6002. OnAutoRuning(new RunEventArgs(stepIndex, $"缺陷检测全部完成:{defectNames}",
  6003. new List<double>(), 1, 0, AllDefectCount, defectNames == ""?2:3, true));
  6004. OnAutoRuning(new RunEventArgs(timeLen));
  6005. //界面显示
  6006. order.TimeLen = timeLen;
  6007. order.DefectCount = AllDefectCount;
  6008. order.Succeed = true;
  6009. order.ModifyUserCode = order.CreateUserCode = userMgr.LoginUser.Code;
  6010. order.Abnormalities = "";//无异常
  6011. order.RepairCode = "";//无修复人员
  6012. //如SN检测已存在,先删除
  6013. var oldSNOrder = OrderService.GetFirst(m => m.SN == order.SN);
  6014. if (oldSNOrder != null)
  6015. {
  6016. Log("删除记录", $"删除上一重复SN检测记录:SN={oldSNOrder.SN}, Date={oldSNOrder.CreateTime}");
  6017. OrderService.DelNav(oldSNOrder);
  6018. }
  6019. if (!OrderService.InsertNav(order))//导航插入
  6020. Log("保存失败", $"保存生产记录失败!", WarningEnum.Low);
  6021. //更新本批次检测数量
  6022. if (!string.IsNullOrWhiteSpace(model.BatchId))
  6023. {
  6024. var expOrder = Expressionable.Create<Order>()
  6025. .And(m => m.ProductId == model.Id)
  6026. .And(m => m.BatchId == model.BatchId)
  6027. .ToExpression();//注意 这一句 不能少
  6028. CurrProductModel.CompleteCount = OrderService.Count(expOrder);
  6029. }
  6030. //以主键为条件更新CompleteCount单列值
  6031. PdtService.Update(it => new Product() { CompleteCount = CurrProductModel.CompleteCount }, it => it.Id == CurrProductModel.Id);
  6032. //记录日产量
  6033. if (confMgr.SetDailyOutputAdd(out DailyOutput))
  6034. {
  6035. OnAutoRuning(new RunEventArgs(timeLen, DailyOutput));
  6036. SendDailyOutput();
  6037. }
  6038. Log("完成", $"用时 {order.TimeLen} 秒");
  6039. _isAuto = false;
  6040. OnAutoRuning(new RunEventArgs(_isAuto));
  6041. //GotoReadyPosAndIO();
  6042. statusMgr.ClearWarning();
  6043. LedReady();
  6044. statusMgr.GotoNormalStandby();
  6045. SendStatus();
  6046. CurrStepResult = 0;
  6047. CurrPoinntCount = 0;
  6048. CurrProcessIndex = -1;
  6049. #region MES弃用
  6050. //MES上传
  6051. if (confMgr.SysConfigParams.EnableHttp)
  6052. {
  6053. #if false
  6054. string messtr = GetMesString(confMgr.SysConfigParams.HttpTempPath, model, true);
  6055. Log("MES上传", $"Url:{confMgr.SysConfigParams.HttpUrl}, Date={messtr}");
  6056. string rel = "";
  6057. try
  6058. {
  6059. rel = HttpApi.Post(confMgr.SysConfigParams.HttpUrl, HttpApi.HttpContentType.application_json, messtr);
  6060. Log("MES反馈", $"return:{rel}");
  6061. }
  6062. catch (Exception e)
  6063. {
  6064. Log("MES上传失败", $"失败原因:{e.Message}");
  6065. }
  6066. if (!string.IsNullOrEmpty(rel))
  6067. {
  6068. try
  6069. {
  6070. JObject jo = (JObject)JsonConvert.DeserializeObject(rel);
  6071. if (jo != null)
  6072. {
  6073. if (jo.ContainsKey(confMgr.SysConfigParams.HttpReturnKey) && jo[confMgr.SysConfigParams.HttpReturnKey] != null)
  6074. {
  6075. if(jo[confMgr.SysConfigParams.HttpReturnKey].ToString() == confMgr.SysConfigParams.HttpReturnValue)
  6076. Log("MES上传", $"上传数据成功:{rel}");
  6077. else
  6078. Log("MES上传", $"上传数据失败:{rel}", WarningEnum.Low);
  6079. }
  6080. else
  6081. Log("MES上传", $"上传数据无返回结果:{rel}", WarningEnum.Low);
  6082. }
  6083. else
  6084. {
  6085. Log("MES上传", $"上传数据无反应:{rel}", WarningEnum.Low);
  6086. }
  6087. }
  6088. catch (Exception e)
  6089. {
  6090. Log("MES反馈失败", $"失败原因:{e.Message}", WarningEnum.Low);
  6091. }
  6092. }
  6093. #endif
  6094. }
  6095. #endregion
  6096. #region 打印
  6097. if (model.EnableLabelPrint)
  6098. {
  6099. Log("标签打印", $"打印机:{confMgr.SysConfigParams.LabelPrinterName}, 模板路径={model.LabelTempPath}");
  6100. ret = PrintFileData(PrinterType.Label, confMgr.SysConfigParams.LabelPrinterName,
  6101. model.LabelTempPath, CurrPrintInfos, model);
  6102. if(ret)
  6103. Log("标签打印", $"打印成功:{CurrPrintInfos}");
  6104. else
  6105. Log("标签打印", $"打印失败:打印机={confMgr.SysConfigParams.LabelPrinterName}, 模板路径={model.LabelTempPath}, 打印数据={CurrPrintInfos}", WarningEnum.Low);
  6106. }
  6107. if (model.EnableExcelPrint)
  6108. {
  6109. Log("Excel打印", $"打印机:{confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.ExcelTempPath}");
  6110. ret = PrintFileData(PrinterType.Excel, confMgr.SysConfigParams.ExcelPrinterName,
  6111. model.ExcelTempPath, CurrPrintInfos, model);
  6112. if (ret)
  6113. Log("Excel打印", $"打印成功:{CurrPrintInfos}");
  6114. else
  6115. Log("Excel打印", $"打印失败:打印机={confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.ExcelTempPath}, 打印数据={CurrPrintInfos}", WarningEnum.Low);
  6116. }
  6117. //获取当前工单
  6118. CurrDefectOrders = OrderService.GetListNav(order.DetectOrder);
  6119. if (model.EnableOrderPrint && (CurrDefectOrders.Count == TotalCnt))
  6120. {
  6121. DialogResult result = MessageBox.Show($"工单检测完成,数量{CurrDefectOrders.Count},是否打印?", "检验工单打印",
  6122. MessageBoxButtons.YesNo);
  6123. if (result == DialogResult.Yes)
  6124. {
  6125. Log("工单打印", $"打印机:{confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.OrderTempPath}");
  6126. ret = PrintFileOrderData(confMgr.SysConfigParams.ExcelPrinterName,
  6127. model.OrderTempPath, CurrOrderPrintInfos, model);
  6128. if (ret)
  6129. Log("工单打印", $"打印成功!");
  6130. else
  6131. Log("工单打印", $"打印失败:打印机={confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.OrderTempPath}, 打印数据={Newtonsoft.Json.JsonConvert.SerializeObject(CurrOrderPrintInfos)}", WarningEnum.Low);
  6132. }
  6133. }
  6134. //保存excel
  6135. if (model.EnableOrderSave && (CurrDefectOrders.Count == TotalCnt))
  6136. {
  6137. string ExcelSavePath = $"{model.OrderSavePath}\\{order.OrderCode}_{order.SN}_{DateTime.Now.ToString("HHmmss")}.xlsx";
  6138. Log("工单保存", $"模板路径={model.OrderTempPath},保存路径={ExcelSavePath}");
  6139. ret = SaveFileOrderData(ExcelSavePath,
  6140. model.OrderTempPath, CurrOrderPrintInfos, model);
  6141. if (ret)
  6142. Log("工单保存", $"保存成功! 保存数据={Newtonsoft.Json.JsonConvert.SerializeObject(CurrOrderPrintInfos)}");
  6143. else
  6144. Log("工单保存", $"保存失败:保存路径={ExcelSavePath}, 模板路径={model.OrderTempPath}, 保存数据={Newtonsoft.Json.JsonConvert.SerializeObject(CurrOrderPrintInfos)}", WarningEnum.Low);
  6145. }
  6146. if ((model.EnableOrderPrint && (CurrDefectOrders.Count == TotalCnt)) || (model.EnableOrderSave && (CurrDefectOrders.Count == TotalCnt)))
  6147. CurrOrderPrintInfos.Clear();
  6148. #endregion
  6149. return -1;
  6150. }
  6151. else //继续
  6152. {
  6153. if (this.CurrPoinntCount >= TestCnt )
  6154. {
  6155. CurrStepResult = 0;
  6156. this.CurrPoinntCount = 0;
  6157. lstTestData.Clear();
  6158. //新流程需要判断是否跑完该流程所有点位
  6159. return ++stepIndex;
  6160. }
  6161. else
  6162. return stepIndex;
  6163. }
  6164. #endregion
  6165. }
  6166. }
  6167. catch (Exception ex)
  6168. {
  6169. Log("工序", $"[{stepIndex + 1}] Err:" + ex.Message + "\n" + ex.StackTrace, WarningEnum.High);
  6170. return -2;
  6171. }
  6172. }
  6173. #region 缺陷数量
  6174. /// <summary>
  6175. /// 根据缺陷code获取缺陷数量
  6176. /// </summary>
  6177. /// <param name="order"></param>
  6178. /// <param name="defectCode"></param>
  6179. /// <returns></returns>
  6180. private int getDefectCountFromCode(Order order, string defectCode)
  6181. {
  6182. if (order.DefectCntInfoList != null)
  6183. {
  6184. var temp = order.DefectCntInfoList.Find(x => x.Code == defectCode);
  6185. if (temp != null)
  6186. {
  6187. return temp.DefectCnt;
  6188. }
  6189. else
  6190. return 0;
  6191. }
  6192. else
  6193. return 0;
  6194. }
  6195. #endregion
  6196. #region 厚度检测
  6197. /// <summary>
  6198. /// 厚度检测
  6199. /// </summary>
  6200. /// <param name="stepIndex"></param>
  6201. /// <param name="param"></param>
  6202. /// <param name="isBase"></param>
  6203. /// <returns></returns>
  6204. private int HeightProcessTest(int stepIndex, string processName, string param, bool isBase)
  6205. {
  6206. int ret = 0;
  6207. if (!WaitAllAxisDone())//因启用轴异步功能,使用前需等待
  6208. {
  6209. Log($"厚度基准测量", $"轴到位失败!", WarningEnum.High);
  6210. return stepIndex;
  6211. }
  6212. //判断是否有产品
  6213. bool sts;
  6214. if(isBase) //打基准
  6215. {
  6216. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.产品有无), GetIOBitIndex((int)DIName.产品有无), out sts);
  6217. if(sts)
  6218. {
  6219. Log($"厚度基准测量", $"存在产品,请下料,并重新开始!", WarningEnum.High);
  6220. return -1;
  6221. }
  6222. //开启线程自动打基准
  6223. Thread t = new System.Threading.Thread(()=>RunGetHeightValue(stepIndex, processName, param, isBase));
  6224. t.IsBackground = true;
  6225. t.Start();
  6226. }
  6227. return ret;
  6228. }
  6229. private void RunGetHeightValue(int stepIndex, string processName, string param, bool isBase)
  6230. {
  6231. int AxisX = (int)AxisName.Axis0;
  6232. int AxisY = (int)AxisName.Axis2;
  6233. List<int> axislist = new List<int>() { AxisX, AxisY };
  6234. JObject processParam = JObject.Parse(param);
  6235. int TestCnt = processParam.Value<int>("TestCnt");
  6236. DataProcess dataProcess = (DataProcess)processParam.Value<int>("ProcessData");
  6237. int DelayTime = processParam.Value<int>("DelayTime");
  6238. int DataCnt = processParam.Value<int>("DataCnt");
  6239. double OffsetValue = processParam.Value<double>("OffsetValue");
  6240. //List<PointF> Points = processParam.Value<List<PointF>>("Points");
  6241. ThicknessProp thicknessParam = JsonConvert.DeserializeObject<ThicknessProp>(param);
  6242. List<PointF> Points = thicknessParam.Points;
  6243. double VelLow = processParam.Value<double>("VelLow");
  6244. double VelHigh = processParam.Value<double>("VelHigh");
  6245. double Acc = processParam.Value<double>("Acc");
  6246. double Dec = processParam.Value<double>("Dec");
  6247. int WaitTime = processParam.Value<int>("WaitTime");
  6248. //开始循环测试
  6249. //打基准
  6250. if(isBase)
  6251. {
  6252. Log($"厚度基准值-{processName}", processParam.ToString());
  6253. if(TestCnt > Points.Count)
  6254. {
  6255. Log($"厚度基准值-{processName}", $"点位少于测试次数!", WarningEnum.High);
  6256. return;
  6257. }
  6258. for (int i = 0; i < Points.Count; i++)
  6259. {
  6260. Log($"厚度基准值-{processName}", $"点位{i+1}测试");
  6261. Log($"厚度基准值-{processName}",
  6262. $"XY准备(绝对)运动至{Points[i].X},{Points[i].Y}...");
  6263. if (axisDev.CheckDone(AxisX, 20) != 0)
  6264. {
  6265. Log($"厚度基准值-{processName}", $"轴X1到位失败!", WarningEnum.High);
  6266. return;
  6267. }
  6268. if (axisDev.CheckDone(AxisY, 20) != 0)
  6269. {
  6270. Log($"厚度基准值-{processName}", $"轴Y到位失败!", WarningEnum.High);
  6271. return;
  6272. }
  6273. VelocityCurveParams velx = new VelocityCurveParams(Acc, Dec, VelLow, VelHigh, MotionST, GetMMtoPlus((AxisName)AxisX));
  6274. VelocityCurveParams vely = new VelocityCurveParams(Acc, Dec, VelLow, VelHigh, MotionST, GetMMtoPlus((AxisName)AxisY));
  6275. int iret1 = 0;
  6276. int iret2 = 0;
  6277. iret1 = axisDev.MoveAbsValue(AxisX, velx, Points[i].X);
  6278. iret2 = axisDev.MoveAbsValue(AxisY, vely, Points[i].Y);
  6279. if (iret1 != 0)
  6280. {
  6281. Log($"厚度基准值-{processName}", $"轴X1运动失败!", WarningEnum.High);
  6282. return;
  6283. }
  6284. if (iret2 != 0)
  6285. {
  6286. Log($"厚度基准值-{processName}", $"轴Y运动失败!", WarningEnum.High);
  6287. return;
  6288. }
  6289. //多轴同时运行后强制等待各轴完成
  6290. Log($"厚度基准值-{processName}", $"等待轴组运行完成...");
  6291. if (!WaitAxisDone(axislist))
  6292. {
  6293. Log($"厚度基准值-{processName}", $"轴到位失败!", WarningEnum.High);
  6294. return;
  6295. }
  6296. Thread.Sleep(WaitTime);
  6297. Log($"厚度基准值-{processName}", $"轴组运行完成");
  6298. //测厚气缸下降
  6299. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), true);
  6300. Thread.Sleep(confMgr.HeightDoWait);
  6301. //读取数据
  6302. double TempVal = 0;
  6303. List<double> tempDataList = new List<double>();
  6304. for (int j = 0; j < DataCnt; j++)
  6305. {
  6306. Thread.Sleep(DelayTime);
  6307. TempVal = thicknessDev.GetValue();
  6308. if (TempVal < 0)
  6309. {
  6310. Log("厚度读取", "厚度读取失败,忽略此次测试!");
  6311. return;
  6312. }
  6313. tempDataList.Add(TempVal);
  6314. }
  6315. switch (dataProcess)
  6316. {
  6317. case DataProcess.均值:
  6318. TempVal = tempDataList.Average();
  6319. break;
  6320. case DataProcess.最大值:
  6321. TempVal = tempDataList.Max();
  6322. break;
  6323. case DataProcess.最小值:
  6324. TempVal = tempDataList.Min();
  6325. break;
  6326. default:
  6327. TempVal = tempDataList.Average();
  6328. Log("厚度读取", "厚度读取处理错误,启用均值!");
  6329. break;
  6330. }
  6331. TempVal = Math.Round(TempVal, 2);
  6332. Log("厚度读取", $"厚度值基准值{i+1}:{TempVal}");
  6333. lstHeightBase.Add(TempVal);
  6334. //测厚气缸上升
  6335. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), false);
  6336. Thread.Sleep(confMgr.HeightDoWait);
  6337. }
  6338. }
  6339. GotoLoadPos();
  6340. //打开加紧气缸
  6341. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.加紧气缸), GetIOBitIndex((int)DOName.加紧气缸), false);
  6342. IsCurrHeightBase = true;
  6343. Log("厚度读取", $"获取基准值完毕!");
  6344. }
  6345. #endregion
  6346. #region 双控
  6347. /// <summary>
  6348. /// 等待双控按钮按下
  6349. /// </summary>
  6350. /// <returns></returns>
  6351. private bool WaitGetStartSig()
  6352. {
  6353. bool ret = false;
  6354. bool sts;
  6355. if (!IsGetStartSig)
  6356. {
  6357. GotoLoadPos();
  6358. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), true);
  6359. Log($"双控启动", $"等待双控按下....");
  6360. while (true)
  6361. {
  6362. if (isBreakProcessRun())
  6363. {
  6364. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  6365. return false;
  6366. }
  6367. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.双手启动), GetIOBitIndex((int)DIName.双手启动), out sts);
  6368. if (sts)
  6369. {
  6370. if (confMgr.SysConfigParams.OpenPdtIsHave)
  6371. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.产品有无), GetIOBitIndex((int)DIName.产品有无), out sts);
  6372. else
  6373. sts = true;
  6374. if (sts)
  6375. {
  6376. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.加紧气缸), GetIOBitIndex((int)DOName.加紧气缸), true);
  6377. Thread.Sleep(confMgr.ProductDoWait);
  6378. Log($"双控启动", $"双控按钮按下启动");
  6379. IsGetStartSig = true;
  6380. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  6381. return true;
  6382. }
  6383. else
  6384. {
  6385. Log($"双控启动", $"无产品信号");
  6386. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  6387. IsGetStartSig = false;
  6388. return false;
  6389. }
  6390. }
  6391. Thread.Sleep(100);
  6392. }
  6393. }
  6394. else
  6395. return true;
  6396. //return ret;
  6397. }
  6398. #endregion
  6399. #region Mark
  6400. /// <summary>
  6401. /// 自动获取mark位置
  6402. /// </summary>
  6403. /// <param name="StepIndex"></param>
  6404. /// <param name="ProcessName"></param>
  6405. /// <param name="EngineName"></param>
  6406. /// <param name="img"></param>
  6407. /// <param name="gbxBmpPath"></param>
  6408. /// <param name="getPosArray"></param>
  6409. /// <param name="asynRun"></param>
  6410. private bool GetMarkPoints(bool IsMarkPic, int pointIndex, string picName,int StepIndex, string ProcessName, MarkCam marktype,string EngineName, HObject img, string gbxBmpPath, int[] adapter,double[] getPosArray, bool asynRun)
  6411. {
  6412. //HOperatorSet.WriteImage(img, "bmp", 0, "123.bmp");
  6413. if(adapter == null || adapter.Length == 0)
  6414. {
  6415. adapter = new int[9] { 5, 18 ,0,0,0,0,0,0,0};
  6416. }
  6417. else if(adapter.Max() == 0)
  6418. adapter = new int[9] { 5, 18, 0, 0, 0, 0, 0, 0, 0 };
  6419. if (getPosArray == null || getPosArray.Length == 0)
  6420. {
  6421. getPosArray = new double[23];
  6422. }
  6423. int typeIndex = 0;
  6424. scannerCBmpLoc bmpCBmpQueue = new scannerCBmpLoc("",1,2);
  6425. //判断是否是第一次寻找mark
  6426. if (IsMarkPic)
  6427. typeIndex = 3333;
  6428. else
  6429. {
  6430. bmpCBmpQueue = scannerCBmpQueue.Dequeue();
  6431. if (pointIndex == 0)
  6432. typeIndex = marktype == MarkCam.尺寸检测Mark ? 1111 : 111;
  6433. else if (pointIndex == 1)
  6434. typeIndex = marktype == MarkCam.尺寸检测Mark ? 2222 : 222;
  6435. else if (pointIndex == 2)
  6436. typeIndex = marktype == MarkCam.尺寸检测Mark ? 4444 : 444;
  6437. else if (pointIndex == 3)
  6438. typeIndex = marktype == MarkCam.尺寸检测Mark ? 3333 : 333;
  6439. }
  6440. //tag
  6441. string MarkTag = "";
  6442. if (IsMarkPic)
  6443. {
  6444. if (marktype == MarkCam.尺寸检测Mark)
  6445. MarkTag = "F_Mark_" + StepIndex;
  6446. else
  6447. {
  6448. if (pointIndex == 3)
  6449. MarkTag = "B_Pos";
  6450. else
  6451. MarkTag = "B_Mark_" + StepIndex;
  6452. }
  6453. }
  6454. else
  6455. {
  6456. if (marktype == MarkCam.尺寸检测Mark)
  6457. MarkTag = "F_Pos";
  6458. else
  6459. MarkTag = "B_Pos";
  6460. }
  6461. //需要偏移校正,index=0时不能异步 //10,20,30... 
  6462. AutoResetEvent endEvent = new AutoResetEvent(false);
  6463. SizeLib.add(new SizeTask()
  6464. {
  6465. stepIndex = StepIndex,
  6466. processName = ProcessName,
  6467. engineName = EngineName,
  6468. drawingPagePath = gbxBmpPath,
  6469. Himage = IsMarkPic? img.Clone() : bmpCBmpQueue.Himage.Clone(),//bmp/file_path二选一,优先bmp
  6470. file_path = bmpCBmpQueue.Path,
  6471. posX = bmpCBmpQueue.PosX,
  6472. posY = bmpCBmpQueue.PosY,
  6473. sizeTag = MarkTag,
  6474. //2023-10-27
  6475. Adapter = adapter,
  6476. AdapterPos = getPosArray,
  6477. index = typeIndex,//Mark
  6478. ContoursAffineTrans1_Out = this.contoursAffineTrans1_Out,//只有777时才使用最近333输出的结果
  6479. finishEvent = (res) =>
  6480. {
  6481. try
  6482. {
  6483. if (res.index == 111 || res.index == 222 || res.index == 333 || res.index == 444)
  6484. {
  6485. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找缺陷Mark点 Index={res.index},结果记录...");
  6486. if (res.index == 333) this.contoursAffineTrans1_Out = res.ContoursAffineTrans1_Out;//不管成功失败都替换
  6487. if (res.isSucceed)
  6488. {
  6489. Thread.Sleep(100);
  6490. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找缺陷Mark点 Index={res.index}; 当前值:{string.Join(",", res.MarkPointList)}");
  6491. JArray markDatas;
  6492. if (string.IsNullOrWhiteSpace(order.MarkData))
  6493. markDatas = new JArray() { 0, 0, 0, 0, 0, 0, 0, 0 };
  6494. else
  6495. markDatas = JArray.Parse(order.MarkData);
  6496. for (int i = 0; i < res.MarkPointList.Count(); i++)
  6497. if (res.MarkPointList[i] != 0)
  6498. markDatas[i] = res.MarkPointList[i];
  6499. order.MarkData = markDatas.ToString();
  6500. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index},Mark点:{order.MarkData} "));
  6501. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找缺陷Mark点 Index={res.index};合并后:{order.MarkData}");
  6502. }
  6503. else
  6504. {
  6505. OnAutoRuning(new RunEventArgs(res.stepIndex, "Mark寻找", new List<double>(), 0, 0, 0, 3, false));
  6506. Log($"{res.stepIndex + 1}-{res.processName}", $"Mark点计算失败,index:{res.index}.", confMgr.SysConfigParams.OpenMarkErrorStop ? WarningEnum.High : WarningEnum.Normal);
  6507. }
  6508. //保存
  6509. if (confMgr.SysConfigParams.SizeBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeBigImag.SavePath))
  6510. {
  6511. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  6512. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{picName}.bmp";
  6513. if (res.Himage != null)
  6514. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  6515. else
  6516. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  6517. }
  6518. }
  6519. else
  6520. {
  6521. int roundIndex = res.index % 10;
  6522. if (res.isSucceed)
  6523. {
  6524. string tagOutData = "";
  6525. if (res.index == 3333 && !string.IsNullOrWhiteSpace(res.sizeTag))
  6526. {
  6527. tagOutData = $"自动寻找尺寸Mark点位:[{string.Join(",", res.posePT)}]";
  6528. if (res.posePT.Length < 2 || res.posePT.Length % 2 != 0)
  6529. {
  6530. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark出错: {tagOutData}", WarningEnum.High);
  6531. return;
  6532. }
  6533. //2023-10-27
  6534. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark对应Adapter: {string.Join(",", res.Adapter)}", WarningEnum.Normal);
  6535. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark对应AdapterPos: {string.Join(",", res.AdapterPos)}", WarningEnum.Normal);
  6536. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark对应posePT: {tagOutData}", WarningEnum.Normal);
  6537. if (order.SizeTagDataList == null)
  6538. order.SizeTagDataList = new List<SizeTagData>();
  6539. order.SizeTagDataList.Add(new SizeTagData()
  6540. {
  6541. SizeTag = res.sizeTag,
  6542. CreateStepIndex = res.stepIndex + 1,
  6543. posePT = string.Join(",", res.posePT)// 回转 Array.ConvertAll(sNums , double.Parse);
  6544. });
  6545. }
  6546. //OnAutoRuning(new RunEventArgs(liStatocStepIndex,
  6547. // $"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}"));
  6548. //Log($"{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} ");
  6549. }
  6550. //失败
  6551. else
  6552. {
  6553. OnAutoRuning(new RunEventArgs(res.stepIndex, "Mark寻找", new List<double>(), 0, 0, 0, 3, false));
  6554. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark对应Adapter: {string.Join(",", res.Adapter)}", WarningEnum.Normal);
  6555. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark对应AdapterPos: {string.Join(",", res.AdapterPos)}", WarningEnum.Normal);
  6556. Log($"{res.stepIndex + 1}-{res.processName}", $"Mark点计算失败,index:{res.index}.", confMgr.SysConfigParams.OpenMarkErrorStop ? WarningEnum.High : WarningEnum.Normal);
  6557. }
  6558. //保存
  6559. if (confMgr.SysConfigParams.SizeBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeBigImag.SavePath))
  6560. {
  6561. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  6562. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{picName}.bmp";
  6563. if (res.Himage != null)
  6564. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  6565. else
  6566. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  6567. }
  6568. }
  6569. }
  6570. catch (Exception ex)
  6571. {
  6572. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测回调处理异常 index:{res.index},ex={ex.Message}");
  6573. }
  6574. endEvent.Set();//roundIndex=0成功或失败线程返回
  6575. //---
  6576. if (res.Himage != null)
  6577. {
  6578. res.Himage.Dispose();
  6579. res.Himage = null;
  6580. }
  6581. if (res.SaveMat != null)
  6582. {
  6583. res.SaveMat.Dispose();
  6584. res.SaveMat = null;
  6585. }
  6586. }
  6587. });
  6588. //需等上面异步回调中的相对偏移校正完成再继续
  6589. if (!asynRun)
  6590. {
  6591. if (!endEvent.WaitOne(10000))
  6592. {
  6593. Log($"{StepIndex + 1}-{ProcessName}", $"Mark位置获取等待超时,忽略继续!", WarningEnum.Low);
  6594. return false;
  6595. }
  6596. }
  6597. return true;
  6598. }
  6599. #endregion
  6600. #region PT线宽等处理
  6601. /// <summary>
  6602. /// 获取上下限
  6603. /// </summary>
  6604. /// <param name="index"></param>
  6605. /// <param name="data"></param>
  6606. /// <param name="aveData"></param>
  6607. /// <param name="model"></param>
  6608. /// <param name="testParam"></param>
  6609. /// <param name="Max"></param>
  6610. /// <param name="Min"></param>
  6611. /// <param name="TestName"></param>
  6612. private void GetLimitInfo(SizeItemParam sizeItem, double data, PointTestProp testParam,
  6613. out double Max, out double Min, out string TestName )
  6614. {
  6615. //新流程不在使用产品中的上下限,产品上下限只为兼容老流程
  6616. double PtUpper = 0;
  6617. double PtLower = 0;
  6618. string testName = "";
  6619. //上下限设置
  6620. Log($"{sizeItem.Name}值", $"线宽{lstTestData.Count}:{data}");
  6621. if (testParam.OpenUseLimit)
  6622. {
  6623. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6624. PtLower = testParam.StandardValues - testParam.MinLimit;
  6625. }
  6626. else
  6627. {
  6628. PtUpper = 0;
  6629. PtLower = 0;
  6630. }
  6631. testName = sizeItem.Name;
  6632. Max = PtUpper;
  6633. Min = PtLower;
  6634. TestName = testName;
  6635. }
  6636. /// <summary>
  6637. /// 保存均值
  6638. /// </summary>
  6639. /// <param name="stepName"></param>
  6640. /// <param name="testName"></param>
  6641. /// <param name="AveData"></param>
  6642. /// <param name="max"></param>
  6643. /// <param name="min"></param>
  6644. /// <returns></returns>
  6645. private bool AddAverageData(string stepName,string testName, double AveData, double max, double min)
  6646. {
  6647. if (order.SizeDefectAverageInfoList == null)
  6648. order.SizeDefectAverageInfoList = new List<SizeDefectAverageInfo>();
  6649. //寻找对应测试项是否已经保存
  6650. var temp = order.SizeDefectAverageInfoList.Where(x => (x.StepName.Contains(stepName) && x.PointCode.Contains(testName))).FirstOrDefault();
  6651. if (temp == null)
  6652. {
  6653. //为保存数据存入
  6654. order.SizeDefectAverageInfoList.Add(new SizeDefectAverageInfo()
  6655. {
  6656. result = CurrStepResult == 2 ? 2 : 1,
  6657. Max = max,
  6658. Min = min,
  6659. PointCode = testName,
  6660. AverageData = AveData,
  6661. StepName = stepName,
  6662. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6663. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  6664. });
  6665. }
  6666. else
  6667. {
  6668. temp.AverageData = AveData;
  6669. temp.Max = max;
  6670. temp.Min = min;
  6671. }
  6672. return true;
  6673. }
  6674. Mat perImage = new Mat();
  6675. private bool PointTestDef(int stepIndex, string processName, string EngineName, string gbxBmpPath, bool asynRun, Product model, PointTestProp testParam, bool isPtLastPoint, SizeItemParam SizeItem)
  6676. {
  6677. if (scannerCBmpQueue.Count < 1)
  6678. {
  6679. Log($"{stepIndex + 1}-{processName}", $"选点测试检测异常,无源图像!!", WarningEnum.Low);
  6680. return false;
  6681. }
  6682. var bmpCBmpQueue = scannerCBmpQueue.Dequeue();
  6683. Log($"{stepIndex + 1}-{processName}", $"开始选点检测,posX:{bmpCBmpQueue.PosX},posY:{bmpCBmpQueue.PosY},图像队列数量: {scannerCBmpQueue.Count}...");
  6684. int testindex = 0;
  6685. //判断测试项
  6686. if (SizeItem.PointCnt == 1)
  6687. testindex = SizeItem.DefectIndex[0];
  6688. else
  6689. {
  6690. if (!isPtLastPoint)
  6691. testindex = SizeItem.DefectIndex[0];
  6692. else
  6693. testindex = SizeItem.DefectIndex[1];
  6694. }
  6695. //需要偏移校正,index=0时不能异步 //10,20,30... 
  6696. AutoResetEvent endEvent = new AutoResetEvent(false);
  6697. //加入处理
  6698. SizeLib.add(new SizeTask()
  6699. {
  6700. stepIndex = stepIndex,
  6701. processName = processName,
  6702. //sizeTag = sizeTag,
  6703. engineName = EngineName,
  6704. Himage = bmpCBmpQueue.Himage.Clone(),//bmp/file_path二选一,优先bmp
  6705. file_path = bmpCBmpQueue.Path,
  6706. drawingPagePath = gbxBmpPath,
  6707. posX = bmpCBmpQueue.PosX,
  6708. posY = bmpCBmpQueue.PosY,
  6709. index = testindex,//PT
  6710. ContoursAffineTrans1_Out = this.contoursAffineTrans1_Out,//只有777时才使用最近333输出的结果
  6711. //结果回调
  6712. finishEvent = (res) =>
  6713. {
  6714. try
  6715. {
  6716. int roundIndex = res.index % 10;
  6717. bool BeSave = false;
  6718. if (res.isSucceed)
  6719. {
  6720. string tagOutData = "";
  6721. OnAutoRuning(new RunEventArgs(stepIndex,
  6722. $"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}"));
  6723. Log($"{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} ");
  6724. //测量
  6725. //两点测量
  6726. if (isPtLastPoint && (SizeItem.PointCnt == 2))
  6727. {
  6728. //PT测量 等两点测量
  6729. lock (lstTestData)
  6730. {
  6731. double PtData = Math.Round(res.PT1 + testParam.OffsetValue, 4); //单点值
  6732. lstTestData.Add(PtData);
  6733. double PtValue = Math.Round(lstTestData.Average(), 4); //均值
  6734. double PtUpper = 0;
  6735. double PtLower = 0;
  6736. string testName = "";
  6737. //上下限设置
  6738. GetLimitInfo(SizeItem, PtData, testParam, out PtUpper, out PtLower, out testName);
  6739. //OnAutoRuning(new RunEventArgs(22, lstTestData, model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue));
  6740. //数据判定
  6741. double judgData = 0;
  6742. if (testParam.JudgmentData == DataJudgment.单点)
  6743. judgData = PtData;
  6744. else
  6745. judgData = PtValue;
  6746. //当前测试不在范围内,显示小图
  6747. if (PtUpper + PtLower > 0 && (Math.Round(res.PT1 + testParam.OffsetValue, 4) > PtUpper || Math.Round(res.PT1 + testParam.OffsetValue, 4) < PtLower))
  6748. {
  6749. BeSave = true;
  6750. }
  6751. //存在上下限,判断是否为不合格
  6752. if (PtUpper + PtLower > 0 && (judgData > PtUpper || judgData < PtLower))
  6753. {
  6754. //order.Qualified = false;
  6755. CurrStepResult = 2;
  6756. }
  6757. else if ((testParam.JudgmentData == DataJudgment.均值)
  6758. && (PtUpper + PtLower > 0 && !(judgData > PtUpper || judgData < PtLower)))
  6759. {
  6760. //order.Qualified = true;
  6761. CurrStepResult = 0;
  6762. }
  6763. //添加每次测试值
  6764. if (order.SizeDefectInfoList == null)
  6765. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  6766. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  6767. {
  6768. result = CurrStepResult == 2 ? 2 : 1,
  6769. X = res.posX,
  6770. Y = res.posY,
  6771. PointCode = testName,
  6772. Data = PtData,
  6773. StepName = processName,
  6774. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6775. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6776. isAverage = false
  6777. });
  6778. if ((this.CurrPoinntCount + 1) < testParam.PointCnt)
  6779. OnAutoRuning(new RunEventArgs(stepIndex, processName, new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 4),
  6780. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), 1, false));
  6781. else
  6782. {
  6783. //保存最后均值
  6784. order.Qualified = CurrStepResult > 0 ? false : order.Qualified;
  6785. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  6786. {
  6787. result = CurrStepResult == 2 ? 2 : 1,
  6788. X = res.posX,
  6789. Y = res.posY,
  6790. PointCode = testName,
  6791. Data = PtValue,
  6792. StepName = processName,
  6793. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6794. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6795. isAverage = true
  6796. });
  6797. //添加均值数据
  6798. AddAverageData(processName, testName, PtValue, PtUpper, PtLower);
  6799. //打印
  6800. PrintDataList(processName, testParam, PtValue, PtUpper, PtLower);
  6801. OnAutoRuning(new RunEventArgs(stepIndex, processName, new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 4),
  6802. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), CurrStepResult > 0 ? 3 : 2, false));
  6803. }
  6804. }
  6805. }
  6806. //单点测量
  6807. else if (isPtLastPoint && (SizeItem.PointCnt == 1))
  6808. {
  6809. perImage = null;
  6810. //线宽测量 等单点测量
  6811. lock (lstTestData)
  6812. {
  6813. double lineWidthValue = res.Shanxian > 0 ? Math.Round(res.Shanxian + testParam.OffsetValue, 4) : 0;
  6814. lstTestData.Add(lineWidthValue);
  6815. double LwValue = Math.Round(lstTestData.Average(), 4);
  6816. double LwUpper = 0;
  6817. double LwLower = 0;
  6818. string testName = "";
  6819. //上下限设置
  6820. GetLimitInfo(SizeItem, lineWidthValue, testParam, out LwUpper, out LwLower, out testName);
  6821. //OnAutoRuning(new RunEventArgs(23, lstTestData, model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue));
  6822. //数据判定
  6823. double judgData = 0;
  6824. if (testParam.JudgmentData == DataJudgment.单点)
  6825. judgData = lineWidthValue;
  6826. else
  6827. judgData = LwValue;
  6828. //当前测试不在范围内,显示小图
  6829. if (LwUpper + LwLower > 0 && (Math.Round(res.Shanxian + testParam.OffsetValue, 4) > LwUpper || Math.Round(res.Shanxian + testParam.OffsetValue, 4) < LwLower))
  6830. {
  6831. BeSave = true;
  6832. }
  6833. //存在上下限,判断是否为不合格
  6834. if (LwUpper + LwLower > 0 && (judgData > LwUpper || judgData < LwLower))
  6835. {
  6836. //order.Qualified = false;
  6837. CurrStepResult = 2;
  6838. }
  6839. else if ((testParam.JudgmentData == DataJudgment.均值)
  6840. &&(LwUpper + LwLower > 0 && !(judgData > LwUpper || judgData < LwLower)))
  6841. {
  6842. //order.Qualified = true;
  6843. CurrStepResult = 0;
  6844. }
  6845. //添加测试数据
  6846. if (order.SizeDefectInfoList == null)
  6847. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  6848. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  6849. {
  6850. result = CurrStepResult == 2 ? 2 : 1,
  6851. X = res.posX,
  6852. Y = res.posY,
  6853. PointCode = testName,
  6854. Data = lineWidthValue,
  6855. StepName = processName,
  6856. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6857. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6858. isAverage = false
  6859. });
  6860. if ((this.CurrPoinntCount + 1) < testParam.PointCnt)
  6861. OnAutoRuning(new RunEventArgs(stepIndex, processName, new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 2),
  6862. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), 1, false));
  6863. else
  6864. {
  6865. //添加均值数据
  6866. AddAverageData(processName, testName, LwValue, LwUpper, LwLower);
  6867. order.Qualified = CurrStepResult > 0 ? false : order.Qualified;
  6868. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  6869. {
  6870. result = CurrStepResult == 2 ? 2 : 1,
  6871. X = res.posX,
  6872. Y = res.posY,
  6873. PointCode = testName,
  6874. Data = Math.Round(lstTestData.Average(), 4),
  6875. StepName = processName,
  6876. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6877. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6878. isAverage = true
  6879. });
  6880. //打印
  6881. PrintDataList(processName, testParam, LwValue, LwUpper, LwLower);
  6882. OnAutoRuning(new RunEventArgs(stepIndex, processName, new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 2),
  6883. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), CurrStepResult > 0 ? 3 : 2, false));
  6884. }
  6885. }
  6886. }
  6887. //其他距离检测
  6888. else
  6889. {
  6890. if (res.SaveMat != null)
  6891. {
  6892. perImage = res.SaveMat.Clone();
  6893. }
  6894. }
  6895. }
  6896. //失败
  6897. else
  6898. {
  6899. //两点测量
  6900. if (isPtLastPoint && (SizeItem.PointCnt == 2))
  6901. {
  6902. //PT测量
  6903. lock (lstTestData)
  6904. {
  6905. lstTestData.Add(0);
  6906. double PtValue = Math.Round(lstTestData.Average(), 4);
  6907. string testName = "";
  6908. double PtUpper = 0;
  6909. double PtLower = 0;
  6910. GetLimitInfo(SizeItem, 0, testParam, out PtUpper, out PtLower, out testName);
  6911. //OnAutoRuning(new RunEventArgs(stepIndex, processName, lstPT, Math.Round(lstPT.Average(), 4),
  6912. // Math.Round(lstPT.Max(), 4), Math.Round(lstPT.Min(), 4), 3, false));
  6913. order.Qualified = false;
  6914. CurrStepResult = 2;
  6915. //添加测试值
  6916. if (order.SizeDefectInfoList == null)
  6917. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  6918. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  6919. {
  6920. result = CurrStepResult == 2 ? 2 : 1,
  6921. X = res.posX,
  6922. Y = res.posY,
  6923. PointCode = testName,
  6924. Data = 0,
  6925. StepName = processName,
  6926. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6927. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6928. isAverage = false
  6929. });
  6930. if ((this.CurrPoinntCount + 1) < testParam.PointCnt)
  6931. OnAutoRuning(new RunEventArgs(stepIndex, processName + ":检测失败", new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 4),
  6932. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), 1, false));
  6933. else
  6934. {
  6935. //添加均值数据
  6936. AddAverageData(processName, testName, PtValue, PtUpper, PtLower);
  6937. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  6938. {
  6939. result = CurrStepResult == 2 ? 2 : 1,
  6940. X = res.posX,
  6941. Y = res.posY,
  6942. PointCode = testName,
  6943. Data = Math.Round(lstTestData.Average(), 4),
  6944. StepName = processName,
  6945. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6946. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6947. isAverage = true
  6948. });
  6949. PrintDataList(processName, testParam, PtValue, PtUpper, PtLower);
  6950. OnAutoRuning(new RunEventArgs(stepIndex, processName + ":检测失败", new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 4),
  6951. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), CurrStepResult > 0 ? 3 : 2, false));
  6952. }
  6953. }
  6954. }
  6955. //单点测量
  6956. else if (isPtLastPoint && (SizeItem.PointCnt == 1))
  6957. {
  6958. //线宽测量
  6959. lock (lstTestData)
  6960. {
  6961. perImage = null;
  6962. lstTestData.Add(0);
  6963. double LwValue = Math.Round(lstTestData.Average(), 2);
  6964. string testName = "";
  6965. double LwUpper = 0;
  6966. double LwLower = 0;
  6967. GetLimitInfo(SizeItem, 0, testParam, out LwUpper, out LwLower, out testName);
  6968. order.Qualified = false;
  6969. CurrStepResult = 2;
  6970. //添加测试值
  6971. if (order.SizeDefectInfoList == null)
  6972. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  6973. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  6974. {
  6975. result = CurrStepResult == 2 ? 2 : 1,
  6976. X = res.posX,
  6977. Y = res.posY,
  6978. PointCode = testName,
  6979. Data = 0,
  6980. StepName = processName,
  6981. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6982. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  6983. isAverage = false
  6984. });
  6985. if ((this.CurrPoinntCount + 1) < testParam.PointCnt)
  6986. OnAutoRuning(new RunEventArgs(stepIndex, processName + ":检测失败", lstTestData, Math.Round(lstTestData.Average(), 2),
  6987. Math.Round(lstTestData.Max(), 2), Math.Round(lstTestData.Min(), 2), 1, false));
  6988. else
  6989. {
  6990. //添加均值数据
  6991. AddAverageData(processName, testName, LwValue, LwUpper, LwLower);
  6992. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  6993. {
  6994. result = CurrStepResult == 2 ? 2 : 1,
  6995. X = res.posX,
  6996. Y = res.posY,
  6997. PointCode = testName,
  6998. Data = Math.Round(lstTestData.Average(), 4),
  6999. StepName = processName,
  7000. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7001. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7002. isAverage = true
  7003. });
  7004. PrintDataList(processName, testParam, LwValue, LwUpper, LwLower);
  7005. OnAutoRuning(new RunEventArgs(stepIndex, processName + ":检测失败", lstTestData, Math.Round(lstTestData.Average(), 2),
  7006. Math.Round(lstTestData.Max(), 2), Math.Round(lstTestData.Min(), 2), CurrStepResult > 0 ? 3 : 2, false));
  7007. }
  7008. }
  7009. }
  7010. else if(!isPtLastPoint && (SizeItem.PointCnt == 2))//两点第一点
  7011. {
  7012. if (res.SaveMat != null)
  7013. {
  7014. perImage = res.SaveMat.Clone();
  7015. }
  7016. }
  7017. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"失败:{res.resultInfo}"));
  7018. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测失败index:{res.index}:{res.resultInfo}");
  7019. }
  7020. //显示小图
  7021. if ((res.SaveMat != null) && (BeSave))
  7022. {
  7023. if (perImage != null)
  7024. showSizeDefectSmallBmps(perImage, $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}_DB0.bmp");
  7025. showSizeDefectSmallBmps(res.SaveMat, $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}_DB1.bmp");
  7026. }
  7027. //保存
  7028. if (confMgr.SysConfigParams.SizeBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeBigImag.SavePath))
  7029. {
  7030. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7031. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}.bmp";
  7032. if (res.Himage != null)
  7033. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  7034. else
  7035. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  7036. lock (ImageSaveObj)
  7037. {
  7038. path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7039. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}";
  7040. if (res.SaveMat != null)
  7041. {
  7042. //显示
  7043. //OnAutoRuning(new RunEventArgs(0, res.SaveMat));
  7044. res.SaveMat.ImWrite(path + "_DB.bmp");
  7045. }
  7046. }
  7047. }
  7048. }
  7049. catch (Exception ex)
  7050. {
  7051. Log($"{res.stepIndex + 1}-{res.processName}", $"单点检测回调处理异常 index:{res.index},ex={ex.Message}");
  7052. }
  7053. endEvent.Set();//roundIndex=0成功或失败线程返回
  7054. //---
  7055. if (res.Himage != null)
  7056. {
  7057. res.Himage.Dispose();
  7058. res.Himage = null;
  7059. }
  7060. else
  7061. {
  7062. API.DeleteFile(res.file_path);
  7063. }
  7064. if (res.SaveMat != null)
  7065. {
  7066. res.SaveMat.Dispose();
  7067. res.SaveMat = null;
  7068. }
  7069. }
  7070. });
  7071. //需等上面异步回调中的相对偏移校正完成再继续
  7072. if (!asynRun)
  7073. {
  7074. if (!endEvent.WaitOne(60000))
  7075. {
  7076. Log($"{stepIndex + 1}-{processName}", $"单点检测等待超时,忽略继续!", WarningEnum.Low);
  7077. return false;
  7078. }
  7079. }
  7080. return true;
  7081. }
  7082. #endregion
  7083. #region 比对处理
  7084. private bool SizeComp(int stepIndex, string processName, string EngineName, string gbxBmpPath, string picName, bool asynRun)
  7085. {
  7086. if (scannerCBmpQueue.Count < 1)
  7087. {
  7088. Log($"{stepIndex + 1}-{processName}", $"比对检测异常,无源图像!!", WarningEnum.Low);
  7089. return false;
  7090. }
  7091. var bmpCBmpQueue = scannerCBmpQueue.Dequeue();
  7092. Log($"{stepIndex + 1}-{processName}", $"开始比对检测,posX:{bmpCBmpQueue.PosX},posY:{bmpCBmpQueue.PosY},图像队列数量: {scannerCBmpQueue.Count}...");
  7093. //需要偏移校正,index=0时不能异步 //10,20,30... 
  7094. AutoResetEvent endEvent = new AutoResetEvent(false);
  7095. SizeLib.add(new SizeTask()
  7096. {
  7097. stepIndex = stepIndex,
  7098. processName = processName,
  7099. //sizeTag = sizeTag,
  7100. engineName = EngineName,
  7101. Himage = bmpCBmpQueue.Himage.Clone(),//bmp/file_path二选一,优先bmp
  7102. file_path = bmpCBmpQueue.Path,
  7103. drawingPagePath = gbxBmpPath,
  7104. posX = bmpCBmpQueue.PosX,
  7105. posY = bmpCBmpQueue.PosY,
  7106. index = 777,// 比对
  7107. ContoursAffineTrans1_Out = this.contoursAffineTrans1_Out,//只有777时才使用最近333输出的结果
  7108. finishEvent = (res) =>
  7109. {
  7110. try
  7111. {
  7112. //比对
  7113. if (res.index == 777)//比对
  7114. {
  7115. if (res.isSucceed)
  7116. {
  7117. //界面显示
  7118. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},图像比对:{(res.CompResult ? "通过" : "未通过")} "));
  7119. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对,index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},结果:{(res.CompResult ? "通过" : "未通过")}");
  7120. //
  7121. if (order.CompareResult < 2)
  7122. order.CompareResult = res.CompResult ? 1 : 2;
  7123. if (!res.CompResult)
  7124. {
  7125. //不合格
  7126. order.Qualified = false;
  7127. }
  7128. //更新比对看板 对比置零3
  7129. if (!res.CompResult)
  7130. SizeNGCnt++;
  7131. if (SizeNGCnt > 0)
  7132. OnAutoRuning(new RunEventArgs(res.stepIndex, $"图像比对-未通过:index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},结果:{(res.CompResult ? "通过" : "未通过")}", new List<double>(), 0, SizeNGCnt, 0, 1, true));
  7133. //OnAutoRuning(new RunEventArgs(3, false, SizeNGCnt));
  7134. else
  7135. OnAutoRuning(new RunEventArgs(res.stepIndex, $"图像比对-通过:index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},结果:{(res.CompResult ? "通过" : "未通过")}", new List<double>(), 0, SizeNGCnt, 0, 1, true));
  7136. //OnAutoRuning(new RunEventArgs(3, true, SizeNGCnt));
  7137. if (!res.CompResult)
  7138. {
  7139. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对,未通过结果:{JsonConvert.SerializeObject(res.defectInfor2RestorationDesk)}");
  7140. //转为图纸上坐标位置
  7141. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  7142. {
  7143. //AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"转换到图纸后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
  7144. if (order.DefectInfoList == null)
  7145. order.DefectInfoList = new List<DefectInfo>();
  7146. foreach (var item in res.defectInfor2RestorationDeskPage)
  7147. order.DefectInfoList.Add(new DefectInfo()
  7148. {
  7149. Type = 1,
  7150. Code = item[3],
  7151. X = double.Parse(item[1]),
  7152. Y = double.Parse(item[2]),
  7153. ZXD = double.Parse(item[4]),
  7154. ModifyUserCode = userMgr.LoginUser.Code,
  7155. CreateUserCode = userMgr.LoginUser.Code,
  7156. });
  7157. }
  7158. //比对失败的图片 -- 用于修复台调用
  7159. Bitmap bmpCompareFailZoomImage = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.Zoom_Image_mat);
  7160. lstCompareFailZoomImage.Add(bmpCompareFailZoomImage);
  7161. if (confMgr.SysConfigParams.SizeRepairImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeRepairImag.SavePath))
  7162. {
  7163. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeRepairImag.SavePath,
  7164. new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7165. //path += $"Size_SN{order.SN}_I{res.index}_X{res.Defects_X}_Y{res.Defects_Y}_C0_{ model.StepInfo.Name}";
  7166. path += $"Size_SN{order.SN}_I{compBmpIndex}_X{res.posX}_Y{res.posY}_C0_{picName}";
  7167. lock (ImageSaveObj)
  7168. {
  7169. bmpCompareFailZoomImage.Save(path + ".bmp", ImageFormat.Bmp);
  7170. if (res.defectInfor2RestorationDesk != null && res.defectInfor2RestorationDesk.Count > 0)
  7171. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
  7172. }
  7173. }
  7174. //保存不良原图
  7175. if (confMgr.SysConfigParams.SizeNGImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeNGImag.SavePath))
  7176. {
  7177. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeNGImag.SavePath,
  7178. new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7179. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{picName}.bmp";
  7180. Log($"{res.stepIndex + 1}-{processName}", $"未通过图片保存:{path}");
  7181. if (res.Himage != null)
  7182. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  7183. else
  7184. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  7185. }
  7186. }
  7187. }
  7188. else
  7189. {
  7190. order.CompareResult = 2;
  7191. order.Qualified = false;
  7192. SizeNGCnt++;
  7193. OnAutoRuning(new RunEventArgs(res.stepIndex, $"图像比对失败,index:{res.index}-{compBmpIndex}.", new List<double>(), 0, SizeNGCnt, 0, 1, true));
  7194. //OnAutoRuning(new RunEventArgs(3, false, SizeNGCnt));
  7195. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index},图像比对失败!"));
  7196. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对失败,index:{res.index}-{compBmpIndex}.", WarningEnum.Low);
  7197. }
  7198. compBmpIndex++;
  7199. }
  7200. }
  7201. catch (Exception ex)
  7202. {
  7203. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测回调处理异常 index:{res.index},ex={ex.Message}");
  7204. }
  7205. endEvent.Set();//roundIndex=0成功或失败线程返回
  7206. //---
  7207. if (res.Himage != null)
  7208. {
  7209. res.Himage.Dispose();
  7210. res.Himage = null;
  7211. }
  7212. else
  7213. {
  7214. API.DeleteFile(res.file_path);
  7215. }
  7216. if (res.SaveMat != null)
  7217. {
  7218. res.SaveMat.Dispose();
  7219. res.SaveMat = null;
  7220. }
  7221. }
  7222. });
  7223. compBmpNum++;
  7224. //需等上面异步回调中的相对偏移校正完成再继续
  7225. if (!asynRun)
  7226. {
  7227. if (!endEvent.WaitOne(60000))
  7228. {
  7229. Log($"{stepIndex + 1}-{processName}", $"比对等待超时,忽略继续!", WarningEnum.Low);
  7230. return false;
  7231. }
  7232. }
  7233. return true;
  7234. }
  7235. #endregion
  7236. #region 缺陷处理
  7237. private bool DefectPicture(int stepIndex, string processName,SizeDefectProp param, string gbxBmpPath, Product md, string picName)
  7238. {
  7239. int err = 0;
  7240. try
  7241. {
  7242. if (scannerGBmpQueue.Count < 1)
  7243. {
  7244. Log($"{stepIndex + 1}-{processName}", $"缺陷检测异常,无源图像!!", WarningEnum.Low);
  7245. return false;
  7246. }
  7247. var bmpLoc = scannerGBmpQueue.Dequeue();
  7248. Log($"{stepIndex + 1}-{processName}", $"开始缺陷检测,源图索引:{defectBmpNum},图像队列数量: {scannerGBmpQueue.Count}...");
  7249. //string[] aarCut_size = param.CutSize;
  7250. //string[] aarResize = processParam.Value<string>("Resize").Split(',');
  7251. //获取模型类型
  7252. err = 1;
  7253. string modeltp = "pt";
  7254. //Classes tClasses = svcClasses.GetById(md.ClassesId);
  7255. //if (tClasses != null)
  7256. //{
  7257. // if (tClasses.Name == "乳剂")
  7258. // modeltp = "rj";
  7259. // else
  7260. // modeltp = "pt";
  7261. //}
  7262. if (md.DefectModelFile.Replace(".onnx", "") == "rj")
  7263. modeltp = "rj";
  7264. else
  7265. modeltp = "pt";
  7266. err = 2;
  7267. defectLib.add(new DefectTask()
  7268. {
  7269. stepIndex = stepIndex,
  7270. processName = processName,
  7271. modelType = modeltp,
  7272. drawingPagePath = gbxBmpPath,
  7273. //index = defectBmpNum++,
  7274. index = defectBmpNum,
  7275. bmp = bmpLoc.bmp.Clone(),
  7276. Xmm = bmpLoc.Xmm,
  7277. Ymm = bmpLoc.Ymm,
  7278. cut_size = new System.Drawing.Size(param.CutSize.Width, param.CutSize.Height),
  7279. resize = new System.Drawing.Size(param.Resize.Width, param.Resize.Height),
  7280. thresholds = param.Thresholds,
  7281. thresholdsClass = getProductThresholClass(md),
  7282. recAreaThreshold = getProductAreaThreshol(md), //qxName,面积; qxName,面积; qxName,面积;
  7283. finishEvent = (res) =>
  7284. {
  7285. err = 3;
  7286. if (res.isSucceed)
  7287. {
  7288. //界面显示
  7289. OnAutoRuning(new RunEventArgs(res.stepIndex, $"缺陷检测完成(源图索引:{res.index}),缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}",
  7290. new List<double>(), 1, 1, res.defectCount, 1, true));
  7291. //OnAutoRuning(new RunEventArgs(liStatocStepIndex,
  7292. // $"源图索引:{res.index},缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}"));
  7293. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测完成(源图索引:{res.index}),缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}");
  7294. string path = "";
  7295. if (res.defectCount > 0)
  7296. {
  7297. //UI显示小图 (含统计缺陷类型数量)
  7298. AllDefectCount += res.informationList.Count;
  7299. showDefectSmallBmps(res.bmps_tag, res.bmps_cut, res.Xmm, res.Ymm, res.informationList);
  7300. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  7301. {
  7302. Log($"{res.stepIndex + 1}-{res.processName}", $"转换后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
  7303. if (order.DefectInfoList == null)
  7304. order.DefectInfoList = new List<DefectInfo>();
  7305. #if false
  7306. foreach (var item in res.defectInfor2RestorationDeskPage)
  7307. order.DefectInfoList.Add(new DefectInfo()
  7308. {
  7309. Type = 0,
  7310. Code = item[3],
  7311. X = double.Parse(item[1]),
  7312. Y = double.Parse(item[2]),
  7313. ZXD = double.Parse(item[4]),
  7314. Index = int.Parse(item[0]),
  7315. Area = item.Count>5?double.Parse(item[5]):0,
  7316. ModifyUserCode = UserMgr.LoginUser.Code,
  7317. CreateUserCode = UserMgr.LoginUser.Code,
  7318. });
  7319. #else
  7320. for (int i = 0; i < res.defectInfor2RestorationDeskPage.Count; i++)
  7321. {
  7322. double n;
  7323. order.DefectInfoList.Add(new DefectInfo()
  7324. {
  7325. Type = 0,
  7326. Code = res.defectInfor2RestorationDeskPage[i][3],
  7327. X = double.Parse(res.defectInfor2RestorationDeskPage[i][1]),
  7328. Y = double.Parse(res.defectInfor2RestorationDeskPage[i][2]),
  7329. ZXD = double.Parse(res.defectInfor2RestorationDeskPage[i][4]),
  7330. Index = int.Parse(res.defectInfor2RestorationDeskPage[i][0]),
  7331. Area = ((res.defectInfor2RestorationDesk[i].Count > 5) && (double.TryParse(res.defectInfor2RestorationDesk[i][5], out n))) ? double.Parse(res.defectInfor2RestorationDesk[i][5]) : 0,
  7332. ModifyUserCode = UserMgr.LoginUser.Code,
  7333. CreateUserCode = UserMgr.LoginUser.Code,
  7334. });
  7335. }
  7336. #endif
  7337. }
  7338. //保存原始大图
  7339. if (confMgr.SysConfigParams.DefectBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectBigImag.SavePath))
  7340. {
  7341. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7342. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{picName}";
  7343. lock (ImageSaveObj)
  7344. {
  7345. res.bmp.ImWrite(path + ".bmp");
  7346. //OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
  7347. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.informationList));
  7348. }
  7349. }
  7350. //保存小图
  7351. if (confMgr.SysConfigParams.DefectSmallImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectSmallImag.SavePath))
  7352. {
  7353. //2024-03-07 图片index计算
  7354. List<string> indexList = new List<string>();
  7355. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  7356. foreach (var item in res.defectInfor2RestorationDeskPage)
  7357. {
  7358. if (indexList.Count == 0)
  7359. indexList.Add(item[0]);
  7360. else
  7361. {
  7362. if (!indexList.Contains(item[0]))
  7363. indexList.Add(item[0]);
  7364. }
  7365. }
  7366. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectSmallImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7367. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_{picName}";
  7368. if (confMgr.SysConfigParams.OpenFlawDistribution && (res.bmps_tag.Count() != indexList.Count))
  7369. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷图片张数和index对不上:{res.bmps_tag.Count()} - {indexList.Count}", WarningEnum.Low);
  7370. for (int i = 0; i < res.bmps_tag.Count(); i++)
  7371. {
  7372. lock (ImageSaveObj)
  7373. {
  7374. if (res.bmps_tag.Count() != indexList.Count)
  7375. res.bmps_tag[i].Save(path + $"_i{i}_{i}.bmp", ImageFormat.Bmp);
  7376. else
  7377. res.bmps_tag[i].Save(path + $"_i{i}_{indexList[i]}.bmp", ImageFormat.Bmp);
  7378. }
  7379. //res.bmps_tag[i].Save(path + $"_i{i}.bmp", ImageFormat.Bmp);
  7380. //res.bmps_tag[i].Save(path + $"{indexList[i]}.bmp", ImageFormat.Bmp);
  7381. }
  7382. }
  7383. //保存原始小图
  7384. if (confMgr.SysConfigParams.DefectSrcSmallImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectSrcSmallImag.SavePath))
  7385. {
  7386. Log($"{res.stepIndex + 1}-{res.processName}", $"原始小图保存");
  7387. string sinfo = "";
  7388. int sterr = 0;
  7389. try
  7390. {
  7391. for (int i = 0; i < res.defectInfor2RestorationDesk.Count(); i++)
  7392. {
  7393. sterr = 1;
  7394. sinfo = JsonConvert.SerializeObject(res.defectInfor2RestorationDesk[i]);
  7395. int indext = int.Parse(res.defectInfor2RestorationDesk[i][0]);
  7396. double thres = double.Parse(res.defectInfor2RestorationDesk[i][4]);
  7397. if (thres >= confMgr.SysConfigParams.Defect_SrcSmall_Thres)
  7398. {
  7399. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectSrcSmallImag.SavePath,
  7400. new List<string> { order.CreateTime.ToString("yyyyMMdd"),
  7401. md.MainGrid == 1?"主栅":md.DefectModelFile.IndexOf("rj") >= 0?"rj":md.DefectModelFile.IndexOf("pi") >= 0?"pi" : "其他",
  7402. order.SN,
  7403. res.defectInfor2RestorationDesk[i][3]});
  7404. sterr = 2;
  7405. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_{md.StepInfo.Name}";
  7406. res.bmps_cut[indext].ImWrite(path + $"_i{i}.bmp");
  7407. sterr = 3;
  7408. }
  7409. }
  7410. }
  7411. catch (Exception ex)
  7412. {
  7413. Log($"{res.stepIndex + 1}-{res.processName}", $"原始小图保存出错{sterr}-{sinfo}-{path}:{ex.Message}");
  7414. }
  7415. }
  7416. //保存压缩大图 -- 用于修复台调用
  7417. if (confMgr.SysConfigParams.DefectRepairImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectRepairImag.SavePath))
  7418. {
  7419. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectRepairImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7420. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{picName}";
  7421. lock (ImageSaveObj)
  7422. {
  7423. res.bmpCompress.ImWrite(path + ".bmp");
  7424. //OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmpCompress).Save(path + ".bmp", ImageFormat.Bmp);
  7425. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
  7426. }
  7427. }
  7428. }
  7429. else//没有缺陷
  7430. {
  7431. if (confMgr.SysConfigParams.SaveAllImg && confMgr.SysConfigParams.DefectBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectBigImag.SavePath))
  7432. {
  7433. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7434. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{picName}";
  7435. lock (ImageSaveObj)
  7436. {
  7437. res.bmp.ImWrite(path + ".bmp");
  7438. //OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
  7439. }
  7440. }
  7441. }
  7442. }
  7443. else
  7444. {
  7445. OnAutoRuning(new RunEventArgs(res.stepIndex, $"缺陷检测失败:{res.resultInfo}", new List<double>(), 1, -1, -1, 1, true));
  7446. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"失败:{res.resultInfo}"));
  7447. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测失败:{res.resultInfo}");
  7448. //暂停 这里不能暂停,stepIndex和scannerBmpQueue队列也不对了
  7449. }
  7450. defectBmpNumResult++;
  7451. foreach (var item in res.bmps_cut)
  7452. item.Dispose();
  7453. res.bmp.Dispose();
  7454. res.bmp = null;
  7455. res.bmps_tag = null;
  7456. if (res.bmpCompress != null)
  7457. {
  7458. res.bmpCompress.Dispose();
  7459. res.bmpCompress = null;
  7460. }
  7461. System.GC.Collect();
  7462. }
  7463. });
  7464. defectBmpNum++;
  7465. }
  7466. catch (Exception e)
  7467. {
  7468. Log($"{stepIndex + 1}-{processName}", $"Step{err} - {e.Message}!!", WarningEnum.Low);
  7469. return false;
  7470. }
  7471. return true;
  7472. }
  7473. #endregion
  7474. #region 添加缺陷打印信息
  7475. private void AddDefectPrintInfo(SizeDefectProp defectParam)
  7476. {
  7477. if (defectParam.OpenPrint)
  7478. {
  7479. if (!string.IsNullOrEmpty(defectParam.ExcelDefectCount))
  7480. CurrPrintInfos.Add(new PrintInfo()
  7481. {
  7482. Type = 0,
  7483. IsValue = false,
  7484. PrintKey = defectParam.ExcelDefectCount,
  7485. PrintCode = "ExcelDefectCount",
  7486. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7487. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  7488. });
  7489. if (!string.IsNullOrEmpty(defectParam.ExcelDefectEachCount))
  7490. {
  7491. for (int i = 0; i < defectParam.ExcelDefectEachCount.Split(',').Length; i++)
  7492. {
  7493. if (defectParam.LabelDefectEachCount.Split(',')[i] != "##")
  7494. {
  7495. CurrPrintInfos.Add(new PrintInfo()
  7496. {
  7497. Type = 0,
  7498. IsValue = false,
  7499. PrintKey = defectParam.ExcelDefectEachCount.Split(',')[i],
  7500. PrintCode = "ex_" + confMgr.DefectItemParamsList[i].Code,
  7501. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7502. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  7503. });
  7504. }
  7505. }
  7506. }
  7507. }
  7508. if (defectParam.OpenPrintLabel)
  7509. {
  7510. if (!string.IsNullOrEmpty(defectParam.LabelDefectCount))
  7511. CurrPrintInfos.Add(new PrintInfo()
  7512. {
  7513. Type = 1,
  7514. IsValue = false,
  7515. PrintKey = defectParam.LabelDefectCount,
  7516. PrintCode = "LabelDefectCount",
  7517. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7518. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  7519. });
  7520. if (!string.IsNullOrEmpty(defectParam.LabelDefectEachCount))
  7521. {
  7522. for (int i = 0; i < defectParam.LabelDefectEachCount.Split(',').Length; i++)
  7523. {
  7524. if (defectParam.LabelDefectEachCount.Split(',')[i] != "##")
  7525. {
  7526. CurrPrintInfos.Add(new PrintInfo()
  7527. {
  7528. Type = 1,
  7529. IsValue = false,
  7530. PrintKey = defectParam.LabelDefectEachCount.Split(',')[i],
  7531. PrintCode = "lb_" + confMgr.DefectItemParamsList[i].Code,
  7532. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7533. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  7534. });
  7535. }
  7536. }
  7537. }
  7538. }
  7539. }
  7540. #endregion
  7541. #endregion
  7542. #region 日志图片删除
  7543. #region 文件删除
  7544. public void DelectPictureFile()
  7545. {
  7546. //删除文件
  7547. Task.Factory.StartNew(() =>
  7548. {
  7549. //图片
  7550. if (confMgr.SysConfigParams.DefectBigImag.AutoDelete)
  7551. statusMgr.DeleteFiles(confMgr.SysConfigParams.DefectBigImag.SavePath, confMgr.SysConfigParams.DefectBigImag.AutoDeleteDays, true);
  7552. if (confMgr.SysConfigParams.DefectSrcSmallImag.AutoDelete)
  7553. statusMgr.DeleteFiles(confMgr.SysConfigParams.DefectSrcSmallImag.SavePath, confMgr.SysConfigParams.DefectSrcSmallImag.AutoDeleteDays, true);
  7554. if (confMgr.SysConfigParams.DefectSmallImag.AutoDelete)
  7555. statusMgr.DeleteFiles(confMgr.SysConfigParams.DefectSmallImag.SavePath, confMgr.SysConfigParams.DefectSmallImag.AutoDeleteDays, true);
  7556. if (confMgr.SysConfigParams.DefectRepairImag.AutoDelete)
  7557. statusMgr.DeleteFiles(confMgr.SysConfigParams.DefectRepairImag.SavePath, confMgr.SysConfigParams.DefectRepairImag.AutoDeleteDays, true);
  7558. if (confMgr.SysConfigParams.SizeBigImag.AutoDelete)
  7559. statusMgr.DeleteFiles(confMgr.SysConfigParams.SizeBigImag.SavePath, confMgr.SysConfigParams.SizeBigImag.AutoDeleteDays, true);
  7560. if (confMgr.SysConfigParams.SizeNGImag.AutoDelete)
  7561. statusMgr.DeleteFiles(confMgr.SysConfigParams.SizeNGImag.SavePath, confMgr.SysConfigParams.SizeNGImag.AutoDeleteDays, true);
  7562. if (confMgr.SysConfigParams.SizeRepairImag.AutoDelete)
  7563. statusMgr.DeleteFiles(confMgr.SysConfigParams.SizeRepairImag.SavePath, confMgr.SysConfigParams.SizeRepairImag.AutoDeleteDays, true);
  7564. //日志
  7565. if (confMgr.SysConfigParams.AutoDeleteLog)
  7566. statusMgr.DeleteFiles(confMgr.SysConfigParams.LogPath, confMgr.SysConfigParams.AutoDeleteLogData, true);
  7567. });
  7568. }
  7569. #endregion
  7570. #endregion
  7571. #region 系统事件显示回调
  7572. /// <summary>
  7573. /// 初始化回调
  7574. /// </summary>
  7575. /// <param name="sender"></param>
  7576. /// <param name="e"></param>
  7577. public delegate void InitEventHandler(Object sender, InitEventArgs e);
  7578. public event InitEventHandler InitRuning;
  7579. protected virtual void OnInitRuning(InitEventArgs e)
  7580. {
  7581. if (null != InitRuning)
  7582. {
  7583. InitRuning(this, e);
  7584. }
  7585. }
  7586. /// <summary>
  7587. /// 流程回调
  7588. /// </summary>
  7589. /// <param name="sender"></param>
  7590. /// <param name="e"></param>
  7591. public delegate void RunEventHandler(Object sender, RunEventArgs e);
  7592. public event RunEventHandler AutoRuning;
  7593. protected virtual void OnAutoRuning(RunEventArgs e)
  7594. {
  7595. if (null != AutoRuning)
  7596. {
  7597. AutoRuning(this, e);
  7598. }
  7599. }
  7600. /// <summary>
  7601. /// 显图回调
  7602. /// </summary>
  7603. /// <param name="sender"></param>
  7604. /// <param name="e"></param>
  7605. public delegate void ImgEventHandler(Object sender, ImgEventArgs e);
  7606. public event ImgEventHandler AutoShowImg;
  7607. protected virtual void OnAutoShowImg(ImgEventArgs e)
  7608. {
  7609. if (null != AutoShowImg)
  7610. {
  7611. AutoShowImg(this, e);
  7612. }
  7613. }
  7614. /// <summary>
  7615. /// 主窗体回调
  7616. /// </summary>
  7617. /// <param name="sender"></param>
  7618. /// <param name="e"></param>
  7619. public delegate void MainEventHandler(Object sender, MainEventArgs e);
  7620. public event MainEventHandler MainRuning;
  7621. protected virtual void OnMainRuning(MainEventArgs e)
  7622. {
  7623. if (null != MainRuning)
  7624. {
  7625. MainRuning(this, e);
  7626. }
  7627. }
  7628. private void showDefectSmallBmps(Bitmap[] bmps, Mat[] bmps_cut, double Xmm, double Ymm, List<Dictionary<int, List<string>[]>> info)
  7629. {
  7630. OnAutoShowImg(new ImgEventArgs(bmps, bmps_cut, Xmm, Ymm, info));
  7631. }
  7632. #region 尺寸小图
  7633. /// <summary>
  7634. /// 显图回调
  7635. /// </summary>
  7636. /// <param name="sender"></param>
  7637. /// <param name="e"></param>
  7638. public delegate void ImgSizeEventHandler(Object sender, ImgEventArgs e);
  7639. public event ImgSizeEventHandler AutoSizeShowImg;
  7640. protected virtual void OnAutoSizeShowImg(ImgEventArgs e)
  7641. {
  7642. if (null != AutoSizeShowImg)
  7643. {
  7644. AutoSizeShowImg(this, e);
  7645. }
  7646. }
  7647. private void showSizeDefectSmallBmps(Mat bmps_cut, string name)
  7648. {
  7649. OnAutoSizeShowImg(new ImgEventArgs(bmps_cut, name));
  7650. }
  7651. #endregion
  7652. #endregion
  7653. #region 界面显示
  7654. public static void showRowNum_onDataGrid_RowPostPaint(DataGridView dgv, object sender, DataGridViewRowPostPaintEventArgs e)
  7655. {
  7656. Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, dgv.RowHeadersWidth - 4, e.RowBounds.Height);
  7657. TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), dgv.RowHeadersDefaultCellStyle.Font, rectangle, dgv.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
  7658. }
  7659. /// <summary>
  7660. /// IO二进制数据格式化到8位 XXXX10X0
  7661. /// </summary>
  7662. /// <param name="datas"></param>
  7663. /// <returns></returns>
  7664. public static string[] IODataFormatBinaryStr(string[] datas, bool clone, char defaultPadChar = 'X')
  7665. {
  7666. string[] datas2 = new string[datas.Length];
  7667. for (int i = 0; i < datas.Length; i++)
  7668. {
  7669. if (clone)
  7670. {
  7671. datas2[i] = datas[i].Replace(" ", "");
  7672. if (datas2[i].Length > 8)
  7673. datas2[i] = datas2[i].Substring(datas2[i].Length - 8);
  7674. else if (datas2[i].Length < 8)
  7675. datas2[i] = datas2[i].PadLeft(8, defaultPadChar);
  7676. }
  7677. else
  7678. {
  7679. datas[i] = datas[i].Replace(" ", "");
  7680. if (datas[i].Length > 8)
  7681. datas[i] = datas[i].Substring(datas[i].Length - 8);
  7682. else if (datas[i].Length < 8)
  7683. datas[i] = datas[i].PadLeft(8, defaultPadChar);
  7684. datas2 = datas;
  7685. }
  7686. }
  7687. return datas2;
  7688. }
  7689. /// <summary>
  7690. ///
  7691. /// </summary>
  7692. /// <param name="op_show_list">[XXHL XXXX,XXXX XXXX,...]</param>
  7693. /// <param name="currIoDatas">[byte,byte,byte,byte]</param>
  7694. /// <returns></returns>
  7695. public static bool compareIOInput(string[] op_show_list, byte[] currIoDatas)
  7696. {
  7697. int isok = 0;//1-true 2-false
  7698. string IN_OP_SHOW;
  7699. for (int i = 0; i < currIoDatas.Length; i++)
  7700. {
  7701. IN_OP_SHOW = op_show_list[i].Replace(" ", "").PadLeft(8, 'X');
  7702. if (IN_OP_SHOW.IndexOf('H') < 0 && IN_OP_SHOW.IndexOf('L') < 0)
  7703. continue;
  7704. for (int j = 7; j >= 0; j--)
  7705. {
  7706. byte bit = (byte)(1 << 7 - j);
  7707. if (IN_OP_SHOW[j] == 'H')
  7708. {
  7709. if ((bit & currIoDatas[i]) > 0)
  7710. isok = 1;
  7711. else
  7712. {
  7713. isok = 2;
  7714. break;
  7715. }
  7716. }
  7717. else if (IN_OP_SHOW[j] == 'L')
  7718. {
  7719. if ((currIoDatas[i] ^ (currIoDatas[i] | bit)) > 0)
  7720. isok = 1;
  7721. else
  7722. {
  7723. isok = 2;
  7724. break;
  7725. }
  7726. }
  7727. }
  7728. //已经不符
  7729. if (isok == 2) break;
  7730. }
  7731. //
  7732. return isok == 1;
  7733. }
  7734. #endregion
  7735. #region 硬盘检测
  7736. public static bool CheckDisk(IWin32Window owner, int max = 10)
  7737. {
  7738. if (!string.IsNullOrEmpty(ConfMgr.Instance.SysConfigParams.DefectBigImag.SavePath))
  7739. {
  7740. string path = ConfMgr.Instance.SysConfigParams.DefectBigImag.SavePath;
  7741. string volume = path.Substring(0, path.IndexOf(':'));
  7742. long freespace = DiskAPI.GetHardDiskSpace(volume);
  7743. if (freespace < max)
  7744. {
  7745. string tip = $"当前{volume}硬盘容量:{freespace}GB,小于{max}GB。注意清理!!";
  7746. FrmDialog.ShowDialog(owner, tip, "警告", true);
  7747. return false;
  7748. }
  7749. }
  7750. return true;
  7751. }
  7752. #endregion
  7753. #region 自动聚焦
  7754. public bool AutoFocus(double FocusStep, double DirStep, int waitTime, int Timeout)
  7755. {
  7756. DateTime dt;
  7757. double step = FocusStep;
  7758. double dir_step = DirStep;
  7759. int axisno = (int)AxisName.Axis3;
  7760. double z = GetAxisPosValueMM(axisno);
  7761. double mean = 0;
  7762. double z_hpos = 0;
  7763. int cnt = 0;
  7764. int dir = 0;
  7765. DateTime alldt = DateTime.Now;
  7766. Yolo_Class yolo = new Yolo_Class();
  7767. //寻找方向
  7768. dt = DateTime.Now;
  7769. bool breakW = false;
  7770. while (true)
  7771. {
  7772. double pos = GetAxisPosValueMM(axisno);
  7773. for (int i = 0; i < snapCnt; i++)
  7774. {
  7775. camDevFront.ClearImageQueue();
  7776. Acquisition acq = camDevFront.Snap(1, 5000);
  7777. if (acq.GrabStatus == "GrabPass")
  7778. {
  7779. //显示
  7780. OnAutoRuning(new RunEventArgs(0, acq.Image));
  7781. yolo.FocusDirec(acq.Image.CopyObj(1, -1), ref dir, ref mean, ref z_hpos);
  7782. cnt++;
  7783. if ((cnt > 2) && (dir != 0))
  7784. {
  7785. breakW = true;
  7786. Log("自动找方向", $"步进次数:{cnt},位置:{pos}, 反馈方向:{dir}, 反馈位置:{z_hpos}, 步进:{dir_step}");
  7787. break;
  7788. }
  7789. VelocityCurveParams velocityCurve = new VelocityCurveParams(100, 100, 5, 100, 0, 1000);
  7790. //axisDev.MoveAbsValue(axisno, velocityCurve, z - cnt * dir_step);
  7791. if (cnt == 1)
  7792. {
  7793. mean = 0;
  7794. Log("自动找方向", $"步进次数:{cnt},位置:{pos}, mean:{mean}, 反馈方向:{dir}, 反馈位置:{z_hpos}");
  7795. axisDev.MoveAbsValue(axisno, velocityCurve, z_hpos);
  7796. axisDev.CheckDone(axisno, 20);
  7797. }
  7798. else
  7799. {
  7800. Log("自动找方向", $"步进次数:{cnt},位置:{pos}, mean:{mean}, 反馈方向:{dir}, 反馈位置:{z_hpos}, 步进:{dir_step}");
  7801. axisDev.MoveAbsValue(axisno, velocityCurve, pos - dir_step);
  7802. axisDev.CheckDone(axisno, 20);
  7803. }
  7804. break;
  7805. //Log("自动找方向", $"步进次数:{cnt},位置:{z_hpos - cnt * dir_step}, 反馈:{dir}");
  7806. }
  7807. else
  7808. {
  7809. Log($"自动找方向{i}", $"拍照失败!");
  7810. if (i < snapCnt - 1)
  7811. {
  7812. Thread.Sleep(100);
  7813. continue;
  7814. }
  7815. else
  7816. return false;
  7817. }
  7818. }
  7819. if (breakW)
  7820. break;
  7821. if((DateTime.Now - dt).TotalMilliseconds > Timeout)
  7822. {
  7823. return false;
  7824. }
  7825. Thread.Sleep(waitTime);
  7826. }
  7827. cnt = 0;
  7828. mean = 0;
  7829. z = GetAxisPosValueMM(axisno);
  7830. //dt = DateTime.Now;
  7831. //聚焦
  7832. breakW = false;
  7833. while (true)
  7834. {
  7835. double pos = GetAxisPosValueMM(axisno);
  7836. for (int i = 0; i < snapCnt; i++)
  7837. {
  7838. camDevFront.ClearImageQueue();
  7839. Acquisition acq = camDevFront.Snap(1, 1000);
  7840. if (acq.GrabStatus == "GrabPass")
  7841. {
  7842. //显示
  7843. OnAutoRuning(new RunEventArgs(0, acq.Image));
  7844. yolo.Focus(acq.Image.CopyObj(1, -1), step, ref dir, ref z, ref mean);
  7845. cnt++;
  7846. Log("自动聚焦", $"方向:{dir},下次目标位置:{z},次数:{cnt},反馈:{mean},Z轴当前实际位置:{pos}");
  7847. if (mean == 9999)
  7848. {
  7849. breakW = true;
  7850. break;
  7851. }
  7852. VelocityCurveParams velocityCurve = new VelocityCurveParams(100, 100, 5, 100, 0, 1000);
  7853. axisDev.MoveAbsValue(axisno, velocityCurve, z);
  7854. axisDev.CheckDone(axisno, 20);
  7855. if ((DateTime.Now - alldt).TotalMilliseconds > Timeout)
  7856. {
  7857. return false;
  7858. }
  7859. break;
  7860. }
  7861. else
  7862. {
  7863. Log($"自动找方向2{i}", $"拍照失败!");
  7864. if (i < snapCnt - 1)
  7865. {
  7866. Thread.Sleep(100);
  7867. continue;
  7868. }
  7869. else
  7870. return false;
  7871. }
  7872. }
  7873. if (breakW)
  7874. break;
  7875. if ((DateTime.Now - alldt).TotalMilliseconds > Timeout)
  7876. {
  7877. return false;
  7878. }
  7879. }
  7880. return true;
  7881. }
  7882. #endregion
  7883. #region 打印
  7884. public bool PrintFileData(PrinterType printerType, string printerName, string printerTemp, List<PrintInfo> data, Product model)
  7885. {
  7886. bool ret = true;
  7887. try
  7888. {
  7889. //Log("标签打印", $"打印机:{printerName}, 模板路径={printerTemp}");
  7890. if (printerType == PrinterType.Label)
  7891. {
  7892. if (!printControl.BarTenderOpenFile(printerTemp))
  7893. ret = false;
  7894. }
  7895. else if (printerType == PrinterType.Excel)
  7896. {
  7897. if (!printControl.ExcelOpenFile(printerTemp))
  7898. ret = false;
  7899. }
  7900. Dictionary<string, string> printData = new Dictionary<string, string>();
  7901. if (ret)
  7902. {
  7903. if (data != null)
  7904. {
  7905. foreach (var item in data)
  7906. {
  7907. string value = "";
  7908. //直接添加数据
  7909. if((printerType == PrinterType.Label)&& item.Type == 1 && item.IsValue) //标签数据
  7910. {
  7911. if (printData.ContainsKey(item.PrintKey))
  7912. printData.Remove(item.PrintKey);
  7913. printData.Add(item.PrintKey, item.PrintCode);
  7914. }
  7915. else if((printerType == PrinterType.Excel) && item.Type == 0 && item.IsValue) //excel数据
  7916. {
  7917. if (printData.ContainsKey(item.PrintKey))
  7918. printData.Remove(item.PrintKey);
  7919. printData.Add(item.PrintKey, item.PrintCode);
  7920. }
  7921. else if ((printerType == PrinterType.Label) && item.Type == 1 && !item.IsValue) //标签Code
  7922. {
  7923. switch (item.PrintCode)
  7924. {
  7925. case "料号批次":
  7926. value = order.BatchId;
  7927. break;
  7928. case "外观比对":
  7929. value = order.CompareResult == 0 ? "未比对" : order.CompareResult == 1 ? "OK" : "NG";
  7930. break;
  7931. case "检测结果":
  7932. value = order.Qualified ? "合格" : "不合格";
  7933. break;
  7934. case "料号":
  7935. value = order.OrderCode;
  7936. break;
  7937. case "料号名称":
  7938. if (model != null)
  7939. value = model.Name;
  7940. else
  7941. value = "No Find";
  7942. break;
  7943. case "网版编码":
  7944. value = order.SN;
  7945. break;
  7946. case "检测单号":
  7947. value = order.DetectOrder;
  7948. break;
  7949. case "检测时间":
  7950. value = order.CreateTime.ToString("yyyy/MM/dd HH:mm");
  7951. break;
  7952. case "操作员":
  7953. value = userMgr.LoginUser.Name;
  7954. break;
  7955. case "LabelDefectCount":
  7956. value = order.DefectCount.ToString();
  7957. break;
  7958. default:
  7959. if(item.PrintCode.Contains("lb_"))
  7960. value = order.DefectCntInfoList.Find(x => x.Code == item.PrintCode.Remove(0,3)).DefectCnt.ToString();
  7961. break;
  7962. }
  7963. if (printData.ContainsKey(item.PrintKey))
  7964. printData.Remove(item.PrintKey);
  7965. printData.Add(item.PrintKey, item.PrintCode);
  7966. }
  7967. else if ((printerType == PrinterType.Excel) && item.Type == 0 && !item.IsValue) //excel Code
  7968. {
  7969. switch (item.PrintCode)
  7970. {
  7971. case "料号批次":
  7972. value = order.BatchId;
  7973. break;
  7974. case "外观比对":
  7975. value = order.CompareResult == 0 ? "未比对" : order.CompareResult == 1 ? "OK" : "NG";
  7976. break;
  7977. case "检测结果":
  7978. value = order.Qualified ? "合格" : "不合格";
  7979. break;
  7980. case "料号":
  7981. value = order.OrderCode;
  7982. break;
  7983. case "料号名称":
  7984. if (model != null)
  7985. value = model.Name;
  7986. else
  7987. value = "No Find";
  7988. break;
  7989. case "网版编码":
  7990. value = order.SN;
  7991. break;
  7992. case "检测单号":
  7993. value = order.DetectOrder;
  7994. break;
  7995. case "检测时间":
  7996. value = order.CreateTime.ToString("yyyy/MM/dd HH:mm");
  7997. break;
  7998. case "操作员":
  7999. value = userMgr.LoginUser.Name;
  8000. break;
  8001. #region 缺陷信息
  8002. case "ExcelDefectCount":
  8003. value = order.DefectCount.ToString();
  8004. break;
  8005. default:
  8006. if (item.PrintCode.Contains("ex_"))
  8007. value = order.DefectCntInfoList.Find(x => x.Code == item.PrintCode.Remove(0, 3)).DefectCnt.ToString();
  8008. break;
  8009. #endregion
  8010. }
  8011. if (printData.ContainsKey(item.PrintKey))
  8012. printData.Remove(item.PrintKey);
  8013. printData.Add(item.PrintKey, item.PrintCode);
  8014. }
  8015. }
  8016. }
  8017. }
  8018. if ((ret) && (printerType == PrinterType.Label))
  8019. {
  8020. if (data != null)
  8021. if (!printControl.BarTenderSetData(printData))
  8022. ret = false;
  8023. if (!printControl.BarTenderPrint(printerName))
  8024. ret = false;
  8025. }
  8026. else if ((ret) && (printerType == PrinterType.Excel))
  8027. {
  8028. //只是要sheet1
  8029. printControl.ExcelSelectSheet(1);
  8030. if (data != null)
  8031. if (!printControl.ExcelSetDataValue(printData))
  8032. ret = false;
  8033. if (!printControl.ExcelPrintData(printerName))
  8034. ret = false;
  8035. printControl.ExcelClose();
  8036. }
  8037. }
  8038. catch (Exception ex)
  8039. {
  8040. Log("标签打印", $"打印失败: {ex.Message}", WarningEnum.Low);
  8041. ret = false;
  8042. }
  8043. return ret;
  8044. }
  8045. public bool PrintFileOrderData(string printerName, string printerTemp, List<PrintInfo> data, Product model)
  8046. {
  8047. bool ret = true;
  8048. try
  8049. {
  8050. if (!printControl.ExcelOpenFile(printerTemp))
  8051. ret = false;
  8052. Dictionary<string, string> printData = new Dictionary<string, string>();
  8053. if (ret)
  8054. {
  8055. if (data != null)
  8056. {
  8057. foreach (var item in data)
  8058. {
  8059. string value = "";
  8060. //直接添加数据
  8061. if (item.Type == 3 && item.IsValue) //excel数据
  8062. {
  8063. if(!printData.ContainsKey(item.PrintKey))
  8064. printData.Add(item.PrintKey, item.PrintCode);
  8065. else
  8066. {
  8067. printData.Remove(item.PrintKey);
  8068. printData.Add(item.PrintKey, item.PrintCode);
  8069. }
  8070. }
  8071. else if ( item.Type == 3 && !item.IsValue) //excel Code
  8072. {
  8073. switch (item.PrintCode)
  8074. {
  8075. case "料号批次":
  8076. value = order.BatchId;
  8077. break;
  8078. case "外观比对":
  8079. if(CurrDefectOrders != null)
  8080. {
  8081. value = CurrDefectOrders.Exists(t => t.CompareResult == 2) ? "不通过" : "通过";
  8082. }
  8083. break;
  8084. case "检测结果":
  8085. if (CurrDefectOrders != null)
  8086. {
  8087. value = CurrDefectOrders.Exists(t => t.Qualified == false) ? "不合格" : "合格";
  8088. }
  8089. //value = order.Qualified ? "合格" : "不合格";
  8090. break;
  8091. case "检测数量":
  8092. value = TotalCnt.ToString();
  8093. break;
  8094. case "合格数量":
  8095. if (CurrDefectOrders != null)
  8096. {
  8097. value = CurrDefectOrders.FindAll(t => t.Qualified == true).Count.ToString();
  8098. }
  8099. break;
  8100. case "不合格数量":
  8101. if (CurrDefectOrders != null)
  8102. {
  8103. value = CurrDefectOrders.FindAll(t => t.Qualified == false).Count.ToString();
  8104. }
  8105. break;
  8106. case "料号":
  8107. value = order.OrderCode;
  8108. break;
  8109. case "料号名称":
  8110. if (model != null)
  8111. value = model.Name;
  8112. else
  8113. value = "No Find";
  8114. break;
  8115. case "网版编码":
  8116. value = order.SN;
  8117. break;
  8118. case "检测单号":
  8119. value = order.DetectOrder;
  8120. break;
  8121. case "检测时间":
  8122. value = order.CreateTime.ToString("yyyy/MM/dd HH:mm");
  8123. break;
  8124. case "检测日期":
  8125. value = order.CreateTime.ToString("yyyy/MM/dd");
  8126. break;
  8127. case "操作员":
  8128. value = userMgr.LoginUser.Name;
  8129. break;
  8130. case "综合":
  8131. if (CurrDefectOrders != null)
  8132. {
  8133. List<SizeDefectInfo> frt = new List<SizeDefectInfo>();
  8134. for (int i = 0; i < CurrDefectOrders.Count; i++)
  8135. {
  8136. //获取当前步骤的均值结果
  8137. var tyy = CurrDefectOrders[i].SizeDefectInfoList.FindAll(t => (t.StepName == item.PrintName && t.isAverage == true));
  8138. if (tyy != null && tyy.Count > 0)
  8139. frt.AddRange(tyy);
  8140. }
  8141. value = frt.Exists(t => t.result == 2) ? "不合格" : "合格";
  8142. }
  8143. break;
  8144. #region 缺陷信息
  8145. case "ExcelDefectCount":
  8146. value = order.DefectCount.ToString();
  8147. break;
  8148. #endregion
  8149. }
  8150. if (!printData.ContainsKey(item.PrintKey))
  8151. printData.Add(item.PrintKey, value);
  8152. }
  8153. }
  8154. }
  8155. }
  8156. //只是要sheet1
  8157. printControl.ExcelSelectSheet(1);
  8158. if (data != null)
  8159. if (!printControl.ExcelSetDataValue(printData))
  8160. ret = false;
  8161. if (!printControl.ExcelPrintData(printerName))
  8162. ret = false;
  8163. printControl.ExcelClose();
  8164. }
  8165. catch (Exception ex)
  8166. {
  8167. Log("标签打印", $"打印失败: {ex.Message}", WarningEnum.Low);
  8168. ret = false;
  8169. }
  8170. return ret;
  8171. }
  8172. public bool SaveFileOrderData(string printerName, string printerTemp, List<PrintInfo> data, Product model)
  8173. {
  8174. bool ret = true;
  8175. try
  8176. {
  8177. if (!printControl.ExcelOpenFile(printerTemp))
  8178. ret = false;
  8179. Dictionary<string, string> printData = new Dictionary<string, string>();
  8180. if (ret)
  8181. {
  8182. if (data != null)
  8183. {
  8184. foreach (var item in data)
  8185. {
  8186. string value = "";
  8187. //直接添加数据
  8188. if (item.Type == 3 && item.IsValue) //excel数据
  8189. {
  8190. if (!printData.ContainsKey(item.PrintKey))
  8191. printData.Add(item.PrintKey, item.PrintCode);
  8192. else
  8193. {
  8194. printData.Remove(item.PrintKey);
  8195. printData.Add(item.PrintKey, item.PrintCode);
  8196. }
  8197. }
  8198. else if (item.Type == 3 && !item.IsValue) //excel Code
  8199. {
  8200. switch (item.PrintCode)
  8201. {
  8202. case "料号批次":
  8203. value = order.BatchId;
  8204. break;
  8205. case "外观比对":
  8206. if (CurrDefectOrders != null)
  8207. {
  8208. value = CurrDefectOrders.Exists(t => t.CompareResult == 2) ? "不通过" : "通过";
  8209. }
  8210. break;
  8211. case "检测结果":
  8212. if (CurrDefectOrders != null)
  8213. {
  8214. value = CurrDefectOrders.Exists(t => t.Qualified == false) ? "不合格" : "合格";
  8215. }
  8216. //value = order.Qualified ? "合格" : "不合格";
  8217. break;
  8218. case "检测数量":
  8219. value = TotalCnt.ToString();
  8220. break;
  8221. case "合格数量":
  8222. if (CurrDefectOrders != null)
  8223. {
  8224. value = CurrDefectOrders.FindAll(t => t.Qualified == true).Count.ToString();
  8225. }
  8226. break;
  8227. case "不合格数量":
  8228. if (CurrDefectOrders != null)
  8229. {
  8230. value = CurrDefectOrders.FindAll(t => t.Qualified == false).Count.ToString();
  8231. }
  8232. break;
  8233. case "料号":
  8234. value = order.OrderCode;
  8235. break;
  8236. case "料号名称":
  8237. if (model != null)
  8238. value = model.Name;
  8239. else
  8240. value = "No Find";
  8241. break;
  8242. case "网版编码":
  8243. value = order.SN;
  8244. break;
  8245. case "检测单号":
  8246. value = order.DetectOrder;
  8247. break;
  8248. case "检测时间":
  8249. value = order.CreateTime.ToString("yyyy/MM/dd HH:mm");
  8250. break;
  8251. case "检测日期":
  8252. value = order.CreateTime.ToString("yyyy/MM/dd");
  8253. break;
  8254. case "操作员":
  8255. value = userMgr.LoginUser.Name;
  8256. break;
  8257. case "综合":
  8258. if (CurrDefectOrders != null)
  8259. {
  8260. List<SizeDefectInfo> frt = new List<SizeDefectInfo>();
  8261. for (int i = 0; i < CurrDefectOrders.Count; i++)
  8262. {
  8263. //获取当前步骤的均值结果
  8264. var tyy = CurrDefectOrders[i].SizeDefectInfoList.FindAll(t => (t.StepName == item.PrintName && t.isAverage == true));
  8265. if (tyy != null && tyy.Count > 0)
  8266. frt.AddRange(tyy);
  8267. }
  8268. value = frt.Exists(t => t.result == 2) ? "不合格" : "合格";
  8269. }
  8270. break;
  8271. #region 缺陷信息
  8272. case "ExcelDefectCount":
  8273. value = order.DefectCount.ToString();
  8274. break;
  8275. #endregion
  8276. }
  8277. if (!printData.ContainsKey(item.PrintKey))
  8278. printData.Add(item.PrintKey, value);
  8279. }
  8280. }
  8281. }
  8282. }
  8283. //只是要sheet1
  8284. printControl.ExcelSelectSheet(1);
  8285. if (data != null)
  8286. if (!printControl.ExcelSetDataValue(printData))
  8287. ret = false;
  8288. if (!printControl.ExcelSave(printerName))
  8289. ret = false;
  8290. printControl.ExcelClose();
  8291. }
  8292. catch (Exception ex)
  8293. {
  8294. Log("保存", $"保存失败: {ex.Message}", WarningEnum.Low);
  8295. ret = false;
  8296. }
  8297. return ret;
  8298. }
  8299. #endregion
  8300. #region 获取Mes上传数据
  8301. private string GetMesString(string mesJsonTemp, Product model, bool isNewStep)
  8302. {
  8303. string jsonData = "";
  8304. string txt = "";
  8305. try
  8306. {
  8307. var fileDir = mesJsonTemp;
  8308. byte[] allBytes = null;
  8309. byte[] buffer = new byte[1024];//一个1K的缓冲字节容器
  8310. Stopwatch stopwatch = new Stopwatch();
  8311. stopwatch.Restart();
  8312. using (MemoryStream ms = new MemoryStream())
  8313. {
  8314. using (FileStream fs = new FileStream(fileDir, FileMode.Open, FileAccess.Read))
  8315. {
  8316. int positon = 0;
  8317. while ((positon = fs.Read(buffer, 0, buffer.Length)) > 0)
  8318. {
  8319. ms.Write(buffer, 0, positon);
  8320. }
  8321. allBytes = ms.ToArray();
  8322. }
  8323. }
  8324. stopwatch.Stop();
  8325. if (null != allBytes)
  8326. {
  8327. //尝试将字节转成字符串
  8328. txt = System.Text.Encoding.UTF8.GetString(allBytes);
  8329. // this.richTextBox_Result.Text = txt;
  8330. }
  8331. //string[] txtToArray = txt.Split('\r');
  8332. //解析格式
  8333. if (!string.IsNullOrEmpty(txt))
  8334. {
  8335. Type t = typeof(MesCodeEnum);
  8336. FieldInfo[] fieldInfos = t.GetFields();
  8337. foreach (var item in fieldInfos)
  8338. {
  8339. if (item.FieldType.IsEnum)
  8340. {
  8341. switch ((MesCodeEnum)t.InvokeMember(item.Name, BindingFlags.GetField, null, null, null))
  8342. {
  8343. case MesCodeEnum.MM0001:
  8344. txt = txt.Replace(item.Name, order.DetectOrder);
  8345. break;
  8346. case MesCodeEnum.MM0002:
  8347. txt = txt.Replace(item.Name, order.OrderCode);
  8348. break;
  8349. case MesCodeEnum.MM0003:
  8350. txt = txt.Replace(item.Name, model.Name);
  8351. break;
  8352. case MesCodeEnum.MM0004:
  8353. txt = txt.Replace(item.Name, order.SN);
  8354. break;
  8355. case MesCodeEnum.MM0005:
  8356. txt = txt.Replace(item.Name, userMgr.LoginUser.Name);
  8357. break;
  8358. case MesCodeEnum.MM0006:
  8359. txt = txt.Replace(item.Name, order.CreateTime.ToString("yyyy/MM/dd HH:mm"));
  8360. break;
  8361. case MesCodeEnum.MM0007:
  8362. txt = txt.Replace(item.Name, order.BatchId);
  8363. break;
  8364. case MesCodeEnum.MM0008:
  8365. txt = txt.Replace(item.Name, order.CompareResult == 0 ? "未比对" : order.CompareResult == 1 ? "OK" : "NG");
  8366. break;
  8367. case MesCodeEnum.MM0009:
  8368. txt = txt.Replace(item.Name, order.Qualified ? "合格" : "不合格");
  8369. break;
  8370. case MesCodeEnum.MM0010:
  8371. txt = txt.Replace(item.Name, order.TensionValue.ToString("0.000"));
  8372. break;
  8373. case MesCodeEnum.MM0011:
  8374. txt = txt.Replace(item.Name, order.HeightValue.ToString("0.000"));
  8375. break;
  8376. case MesCodeEnum.MM0012:
  8377. txt = txt.Replace(item.Name, order.LineWidthValue.ToString("0.000"));
  8378. break;
  8379. case MesCodeEnum.MM0013:
  8380. txt = txt.Replace(item.Name, order.PTValue.ToString("0.0000"));
  8381. break;
  8382. //case MesCodeEnum.MM0014:
  8383. // txt = txt.Replace(item.Name, order.XPTValue.ToString("0.0000"));
  8384. // break;
  8385. case MesCodeEnum.MALL000:
  8386. txt = txt.Replace(item.Name, order.DefectCount.ToString());
  8387. break;
  8388. case MesCodeEnum.MDK000:
  8389. txt = txt.Replace(item.Name, order.DKCount.ToString());
  8390. break;
  8391. case MesCodeEnum.MZW000:
  8392. txt = txt.Replace(item.Name, order.ZWCount.ToString());
  8393. break;
  8394. case MesCodeEnum.MGSYC000:
  8395. txt = txt.Replace(item.Name, order.GSYCCount.ToString());
  8396. break;
  8397. case MesCodeEnum.MQWS000:
  8398. txt = txt.Replace(item.Name, order.XWSCount.ToString());
  8399. break;
  8400. case MesCodeEnum.MQK000:
  8401. txt = txt.Replace(item.Name, order.QKCount.ToString());
  8402. break;
  8403. case MesCodeEnum.MZK000:
  8404. txt = txt.Replace(item.Name, order.ZKCount.ToString());
  8405. break;
  8406. case MesCodeEnum.MPP000:
  8407. txt = txt.Replace(item.Name, order.PPCount.ToString());
  8408. break;
  8409. case MesCodeEnum.MHS000:
  8410. txt = txt.Replace(item.Name, order.HSCount.ToString());
  8411. break;
  8412. case MesCodeEnum.MYX000:
  8413. txt = txt.Replace(item.Name, order.YXCount.ToString());
  8414. break;
  8415. case MesCodeEnum.MXB000:
  8416. txt = txt.Replace(item.Name, order.XBCount.ToString());
  8417. break;
  8418. case MesCodeEnum.MSX000:
  8419. txt = txt.Replace(item.Name, order.SXCount.ToString());
  8420. break;
  8421. }
  8422. }
  8423. }
  8424. }
  8425. //单点数据
  8426. if (!string.IsNullOrEmpty(txt))
  8427. {
  8428. if (!isNewStep)
  8429. {
  8430. txt = txt.Replace("MTV001", order.Tension1.ToString("0.000"));
  8431. txt = txt.Replace("MTV002", order.Tension2.ToString("0.000"));
  8432. txt = txt.Replace("MTV003", order.Tension3.ToString("0.000"));
  8433. txt = txt.Replace("MTV004", order.Tension4.ToString("0.000"));
  8434. txt = txt.Replace("MTV005", order.Tension5.ToString("0.000"));
  8435. txt = txt.Replace("MHV001", order.Height1.ToString("0.000"));
  8436. txt = txt.Replace("MHV002", order.Height2.ToString("0.000"));
  8437. txt = txt.Replace("MHV003", order.Height3.ToString("0.000"));
  8438. txt = txt.Replace("MHV004", order.Height4.ToString("0.000"));
  8439. txt = txt.Replace("MHV005", order.Height5.ToString("0.000"));
  8440. txt = txt.Replace("MYPTV001", order.PT1.ToString("0.0000"));
  8441. txt = txt.Replace("MYPTV002", order.PT2.ToString("0.0000"));
  8442. txt = txt.Replace("MYPTV003", order.PT3.ToString("0.0000"));
  8443. txt = txt.Replace("MYPTV004", order.PT5.ToString("0.0000"));
  8444. txt = txt.Replace("MYPTV005", order.PT6.ToString("0.0000"));
  8445. txt = txt.Replace("MLWV001", order.LineWidth1.ToString("0.000"));
  8446. txt = txt.Replace("MLWV002", order.LineWidth2.ToString("0.000"));
  8447. txt = txt.Replace("MLWV003", order.LineWidth3.ToString("0.000"));
  8448. txt = txt.Replace("MLWV004", order.LineWidth4.ToString("0.000"));
  8449. txt = txt.Replace("MLWV005", order.LineWidth5.ToString("0.000"));
  8450. txt = txt.Replace("MLWV006", order.LineWidth6.ToString("0.000"));
  8451. txt = txt.Replace("MLWV007", order.LineWidth7.ToString("0.000"));
  8452. txt = txt.Replace("MLWV008", order.LineWidth8.ToString("0.000"));
  8453. txt = txt.Replace("MLWV009", order.LineWidth9.ToString("0.000"));
  8454. }
  8455. else
  8456. {
  8457. string[] pointType = new string[11] {"Tension", "Height", "Y轴方向PT值检测" , "线宽正面" , "反面检测" ,
  8458. "X轴方向PT值检测","主栅连接线检测","主栅宽度检测","主栅间距","细栅间距检测","背极宽度"};
  8459. string[] codeType = new string[11] {"MTV00", "MHV00", "MYPTV00" , "MLWV00" , "MLWV00" ,
  8460. "MXPTV00","MTV00","MTV00","MTV00","MTV00","MTV00"};
  8461. for (int i = 0; i < pointType.Length; i++)
  8462. {
  8463. List<SizeDefectInfo> t1 = order.SizeDefectInfoList.Where(q => q.PointCode == pointType[i]).ToList();
  8464. for (int j = 0; j < t1.Count; j++)
  8465. {
  8466. txt = txt.Replace(codeType[i] + (i + 1).ToString(), t1[j].Data.ToString("0.0000"));
  8467. }
  8468. }
  8469. }
  8470. }
  8471. }
  8472. catch (Exception ex) {
  8473. Log("MES数据解析", "解析错误:" + ex.Message, WarningEnum.High);
  8474. }
  8475. jsonData = txt;
  8476. return jsonData;
  8477. }
  8478. #endregion
  8479. #region 缺陷分布
  8480. public bool GetDefectDistribution(out string imagePath, out Order outOrder)
  8481. {
  8482. bool ret = false;
  8483. imagePath = "";
  8484. outOrder = null;
  8485. if (CurrProductModel == null || order == null || order.DefectInfoList == null || order.DefectInfoList.Count < 1)
  8486. {
  8487. string str = "";
  8488. if (CurrProductModel == null)
  8489. str = "无当前产品数据";
  8490. else if (order == null)
  8491. str = "无当前生产数据";
  8492. else if ((order.DefectInfoList == null)||(order.DefectInfoList.Count < 1))
  8493. str = "无当前缺陷数据";
  8494. Log("缺陷分布", $"无数据:{str}", WarningEnum.Low);
  8495. return false;
  8496. }
  8497. //图纸
  8498. try
  8499. {
  8500. string gbxBmpPath = "";
  8501. var attachmentFile = CurrProductModel.AttachmentList.FirstOrDefault(x => x.Type == 0);
  8502. if (attachmentFile != null)
  8503. {
  8504. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  8505. if (!File.Exists(gbxBmpPath + ".bmp"))
  8506. gbxBmpPath = "";
  8507. }
  8508. if (string.IsNullOrEmpty(gbxBmpPath))
  8509. {
  8510. Log("缺陷分布", "图纸文件不存在!", WarningEnum.Low);
  8511. MessageBox.Show("图纸文件不存在!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  8512. return false;
  8513. }
  8514. if (!File.Exists(gbxBmpPath + ".jpg"))//转背景后的图纸文件
  8515. {
  8516. //换背景JPG
  8517. Mat mat = Cv2.ImRead(gbxBmpPath + ".bmp");
  8518. Cv2.CvtColor(mat, mat, ColorConversionCodes.RGB2GRAY);//转灰度图
  8519. for (int i = 0; i < mat.Height; i++)
  8520. {
  8521. for (int j = 0; j < mat.Width; j++)
  8522. {
  8523. if (mat.At<byte>(i, j) == 255)//白色
  8524. mat.Set<byte>(i, j, 0);
  8525. else
  8526. mat.Set<byte>(i, j, 255);
  8527. }
  8528. }
  8529. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat).Save(gbxBmpPath + ".jpg", ImageFormat.Jpeg);
  8530. }
  8531. imagePath = gbxBmpPath + ".jpg";
  8532. outOrder = order;
  8533. return true;
  8534. }
  8535. catch (Exception ex)
  8536. {
  8537. MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
  8538. }
  8539. return ret;
  8540. }
  8541. #endregion
  8542. #region 尺寸缺陷禁用
  8543. public void SetSizeEnable(bool val)
  8544. {
  8545. SizeEnable = val;
  8546. Log("尺寸检测", val?"尺寸启用":"尺寸禁用");
  8547. }
  8548. public void SetDefectEnable(bool val)
  8549. {
  8550. DefectEnable = val;
  8551. Log("缺陷检测", val ? "缺陷启用" : "缺陷禁用");
  8552. }
  8553. #endregion
  8554. #region 打印队列
  8555. private void PrintDataList(string processName, TensionProp TensionParam, double baseValue, double upLimit, double loLimit)
  8556. {
  8557. try
  8558. {
  8559. if (TensionParam.OpenPrint)
  8560. {
  8561. if (!string.IsNullOrEmpty(TensionParam.ExcelData))
  8562. CurrPrintInfos.Add(new PrintInfo()
  8563. {
  8564. Type = 0,
  8565. IsValue = true,
  8566. PrintKey = TensionParam.ExcelData,
  8567. PrintCode = order.TensionValue.ToString("0.00"),
  8568. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8569. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8570. });
  8571. if (!string.IsNullOrEmpty(TensionParam.ExcelLimit))
  8572. CurrPrintInfos.Add(new PrintInfo()
  8573. {
  8574. Type = 0,
  8575. IsValue = true,
  8576. PrintKey = TensionParam.ExcelLimit,
  8577. PrintCode = ((TensionParam.OpenUseLimit)&&(TensionParam.MaxLimit + TensionParam.MinLimit>0)&&
  8578. (TensionParam.MaxLimit == TensionParam .MinLimit))? $"{TensionParam.StandardValues}±{TensionParam.MaxLimit}":
  8579. $"上限:{baseValue+ upLimit}\r\n下限:{baseValue-loLimit}",
  8580. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8581. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8582. });
  8583. }
  8584. if (TensionParam.OpenPrintLabel)
  8585. {
  8586. if (!string.IsNullOrEmpty(TensionParam.ExcelData))
  8587. CurrPrintInfos.Add(new PrintInfo()
  8588. {
  8589. Type = 1,
  8590. IsValue = true,
  8591. PrintKey = TensionParam.ExcelData,
  8592. PrintCode = order.TensionValue.ToString("0.00"),
  8593. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8594. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8595. });
  8596. if (!string.IsNullOrEmpty(TensionParam.ExcelLimit))
  8597. CurrPrintInfos.Add(new PrintInfo()
  8598. {
  8599. Type = 1,
  8600. IsValue = true,
  8601. PrintKey = TensionParam.ExcelLimit,
  8602. PrintCode = ((TensionParam.OpenUseLimit) && (TensionParam.MaxLimit + TensionParam.MinLimit > 0) &&
  8603. (TensionParam.MaxLimit == TensionParam.MinLimit)) ? $"{TensionParam.StandardValues}±{TensionParam.MaxLimit}" :
  8604. $"上限:{baseValue + upLimit}\r\n下限:{baseValue - loLimit}",
  8605. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8606. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8607. });
  8608. }
  8609. if (TensionParam.OpenPrintOrder)
  8610. {
  8611. if (!string.IsNullOrEmpty(TensionParam.OrderData))
  8612. if (CurrDefectIndex < TensionParam.OrderData.Split(',').Length)
  8613. {
  8614. CurrOrderPrintInfos.Add(new PrintInfo()
  8615. {
  8616. Type = 3,
  8617. IsValue = true,
  8618. PrintKey = TensionParam.OrderData.Split(',')[CurrDefectIndex],
  8619. PrintCode = order.TensionValue.ToString("0.00"),
  8620. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8621. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8622. });
  8623. }
  8624. if (!string.IsNullOrEmpty(TensionParam.OrderLimit))
  8625. CurrOrderPrintInfos.Add(new PrintInfo()
  8626. {
  8627. Type = 3,
  8628. IsValue = true,
  8629. PrintKey = TensionParam.OrderLimit,
  8630. PrintCode = ((TensionParam.OpenUseLimit) && (TensionParam.MaxLimit + TensionParam.MinLimit > 0) &&
  8631. (TensionParam.MaxLimit == TensionParam.MinLimit)) ? $"{TensionParam.StandardValues}±{TensionParam.MaxLimit}" :
  8632. $"上限:{baseValue + upLimit}\r\n下限:{baseValue - loLimit}",
  8633. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8634. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8635. });
  8636. if (!string.IsNullOrEmpty(TensionParam.OrderTestName))
  8637. CurrOrderPrintInfos.Add(new PrintInfo()
  8638. {
  8639. Type = 3,
  8640. IsValue = true,
  8641. PrintKey = TensionParam.OrderTestName,
  8642. PrintCode = processName,
  8643. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8644. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8645. });
  8646. if (!string.IsNullOrEmpty(TensionParam.OrderTestResult))
  8647. CurrOrderPrintInfos.Add(new PrintInfo()
  8648. {
  8649. Type = 3,
  8650. IsValue = false,
  8651. PrintKey = TensionParam.OrderTestResult,
  8652. PrintCode = "综合",
  8653. PrintName = processName,
  8654. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8655. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8656. });
  8657. }
  8658. }
  8659. catch (Exception ex)
  8660. {
  8661. throw new Exception($"打印参数错误:{ex.Message}");
  8662. }
  8663. }
  8664. private void PrintDataList(string processName, ThicknessProp ThicknessParam, double baseValue, double upLimit, double loLimit)
  8665. {
  8666. try
  8667. {
  8668. if (ThicknessParam.OpenPrint)
  8669. {
  8670. if (!string.IsNullOrEmpty(ThicknessParam.ExcelData))
  8671. CurrPrintInfos.Add(new PrintInfo()
  8672. {
  8673. Type = 0,
  8674. IsValue = true,
  8675. PrintKey = ThicknessParam.ExcelData,
  8676. PrintCode = order.HeightValue.ToString("0.00"),
  8677. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8678. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8679. });
  8680. if (!string.IsNullOrEmpty(ThicknessParam.ExcelLimit))
  8681. CurrPrintInfos.Add(new PrintInfo()
  8682. {
  8683. Type = 0,
  8684. IsValue = true,
  8685. PrintKey = ThicknessParam.ExcelLimit,
  8686. PrintCode = ((ThicknessParam.OpenUseLimit) && (ThicknessParam.MaxLimit + ThicknessParam.MinLimit > 0) &&
  8687. (ThicknessParam.MaxLimit == ThicknessParam.MinLimit)) ? $"{ThicknessParam.StandardValues}±{ThicknessParam.MaxLimit}" :
  8688. $"上限:{baseValue + upLimit}\r\n下限:{baseValue - loLimit}",
  8689. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8690. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8691. });
  8692. }
  8693. if (ThicknessParam.OpenPrintLabel)
  8694. {
  8695. if (!string.IsNullOrEmpty(ThicknessParam.ExcelData))
  8696. CurrPrintInfos.Add(new PrintInfo()
  8697. {
  8698. Type = 1,
  8699. IsValue = true,
  8700. PrintKey = ThicknessParam.ExcelData,
  8701. PrintCode = order.HeightValue.ToString("0.00"),
  8702. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8703. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8704. });
  8705. if (!string.IsNullOrEmpty(ThicknessParam.ExcelLimit))
  8706. CurrPrintInfos.Add(new PrintInfo()
  8707. {
  8708. Type = 1,
  8709. IsValue = true,
  8710. PrintKey = ThicknessParam.ExcelLimit,
  8711. PrintCode = ((ThicknessParam.OpenUseLimit) && (ThicknessParam.MaxLimit + ThicknessParam.MinLimit > 0) &&
  8712. (ThicknessParam.MaxLimit == ThicknessParam.MinLimit)) ? $"{ThicknessParam.StandardValues}±{ThicknessParam.MaxLimit}" :
  8713. $"上限:{baseValue + upLimit}\r\n下限:{baseValue - loLimit}",
  8714. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8715. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8716. });
  8717. }
  8718. if (ThicknessParam.OpenPrintOrder)
  8719. {
  8720. if (!string.IsNullOrEmpty(ThicknessParam.OrderData))
  8721. if (CurrDefectIndex < ThicknessParam.OrderData.Split(',').Length)
  8722. CurrOrderPrintInfos.Add(new PrintInfo()
  8723. {
  8724. Type = 3,
  8725. IsValue = true,
  8726. PrintKey = ThicknessParam.OrderData.Split(',')[CurrDefectIndex],
  8727. PrintCode = order.HeightValue.ToString("0.00"),
  8728. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8729. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8730. });
  8731. if (!string.IsNullOrEmpty(ThicknessParam.OrderLimit))
  8732. CurrOrderPrintInfos.Add(new PrintInfo()
  8733. {
  8734. Type = 3,
  8735. IsValue = true,
  8736. PrintKey = ThicknessParam.OrderLimit,
  8737. PrintCode = ((ThicknessParam.OpenUseLimit) && (ThicknessParam.MaxLimit + ThicknessParam.MinLimit > 0) &&
  8738. (ThicknessParam.MaxLimit == ThicknessParam.MinLimit)) ? $"{ThicknessParam.StandardValues}±{ThicknessParam.MaxLimit}" :
  8739. $"上限:{baseValue + upLimit}\r\n下限:{baseValue - loLimit}",
  8740. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8741. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8742. });
  8743. if (!string.IsNullOrEmpty(ThicknessParam.OrderTestName))
  8744. CurrOrderPrintInfos.Add(new PrintInfo()
  8745. {
  8746. Type = 3,
  8747. IsValue = true,
  8748. PrintKey = ThicknessParam.OrderTestName,
  8749. PrintCode = processName,
  8750. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8751. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8752. });
  8753. if (!string.IsNullOrEmpty(ThicknessParam.OrderTestResult))
  8754. CurrOrderPrintInfos.Add(new PrintInfo()
  8755. {
  8756. Type = 3,
  8757. IsValue = false,
  8758. PrintKey = ThicknessParam.OrderTestResult,
  8759. PrintCode = "综合",
  8760. PrintName = processName,
  8761. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8762. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8763. });
  8764. }
  8765. }
  8766. catch (Exception ex)
  8767. {
  8768. throw new Exception($"打印参数错误:{ex.Message}");
  8769. }
  8770. }
  8771. private void PrintDataList(string processName, PointTestProp testParam, double data, double upLimit, double loLimit)
  8772. {
  8773. try
  8774. {
  8775. if (testParam.OpenPrint)
  8776. {
  8777. if (!string.IsNullOrEmpty(testParam.ExcelData))
  8778. CurrPrintInfos.Add(new PrintInfo()
  8779. {
  8780. Type = 0,
  8781. IsValue = true,
  8782. PrintKey = testParam.ExcelData,
  8783. PrintCode = data.ToString("0.0000"),
  8784. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8785. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8786. });
  8787. if (!string.IsNullOrEmpty(testParam.ExcelLimit))
  8788. CurrPrintInfos.Add(new PrintInfo()
  8789. {
  8790. Type = 0,
  8791. IsValue = true,
  8792. PrintKey = testParam.ExcelLimit,
  8793. PrintCode = ((testParam.MaxLimit + testParam.MinLimit)>0&&(testParam.MaxLimit == testParam.MinLimit)) ?
  8794. $"{testParam.StandardValues}±{testParam.MaxLimit}" : $"上限:{upLimit}\r\n下限:{loLimit}",
  8795. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8796. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8797. });
  8798. }
  8799. if (testParam.OpenPrintLabel)
  8800. {
  8801. if (!string.IsNullOrEmpty(testParam.ExcelData))
  8802. CurrPrintInfos.Add(new PrintInfo()
  8803. {
  8804. Type = 1,
  8805. IsValue = true,
  8806. PrintKey = testParam.ExcelData,
  8807. PrintCode = data.ToString("0.0000"),
  8808. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8809. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8810. });
  8811. if (!string.IsNullOrEmpty(testParam.ExcelLimit))
  8812. CurrPrintInfos.Add(new PrintInfo()
  8813. {
  8814. Type = 1,
  8815. IsValue = true,
  8816. PrintKey = testParam.ExcelLimit,
  8817. PrintCode = ((testParam.MaxLimit + testParam.MinLimit) > 0 && (testParam.MaxLimit == testParam.MinLimit)) ?
  8818. $"{testParam.StandardValues}±{testParam.MaxLimit}" : $"上限:{upLimit}\r\n下限:{loLimit}",
  8819. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8820. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8821. });
  8822. }
  8823. if (testParam.OpenPrintOrder)
  8824. {
  8825. if (!string.IsNullOrEmpty(testParam.OrderData))
  8826. if (CurrDefectIndex < testParam.OrderData.Split(',').Length)
  8827. CurrOrderPrintInfos.Add(new PrintInfo()
  8828. {
  8829. Type = 3,
  8830. IsValue = true,
  8831. PrintKey = testParam.OrderData.Split(',')[CurrDefectIndex],
  8832. PrintCode = data.ToString("0.0000"),
  8833. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8834. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8835. });
  8836. if (!string.IsNullOrEmpty(testParam.OrderLimit))
  8837. CurrOrderPrintInfos.Add(new PrintInfo()
  8838. {
  8839. Type = 3,
  8840. IsValue = true,
  8841. PrintKey = testParam.OrderLimit,
  8842. PrintCode = ((testParam.MaxLimit + testParam.MinLimit) > 0 && (testParam.MaxLimit == testParam.MinLimit)) ?
  8843. $"{testParam.StandardValues}±{testParam.MaxLimit}" : $"上限:{upLimit}\r\n下限:{loLimit}",
  8844. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8845. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8846. });
  8847. if (!string.IsNullOrEmpty(testParam.OrderTestName))
  8848. CurrOrderPrintInfos.Add(new PrintInfo()
  8849. {
  8850. Type = 3,
  8851. IsValue = true,
  8852. PrintKey = testParam.OrderTestName,
  8853. PrintCode = processName,
  8854. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8855. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8856. });
  8857. if (!string.IsNullOrEmpty(testParam.OrderTestResult))
  8858. CurrOrderPrintInfos.Add(new PrintInfo()
  8859. {
  8860. Type = 3,
  8861. IsValue = false,
  8862. PrintKey = testParam.OrderTestResult,
  8863. PrintCode = "综合",
  8864. PrintName = processName,
  8865. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8866. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8867. });
  8868. }
  8869. }
  8870. catch (Exception ex)
  8871. {
  8872. throw new Exception($"打印参数错误:{ex.Message}");
  8873. }
  8874. }
  8875. #endregion
  8876. }
  8877. #region 系统事件
  8878. /// <summary>
  8879. /// 流程事件
  8880. /// </summary>
  8881. public class RunEventArgs : EventArgs
  8882. {
  8883. private int _cmd;
  8884. public int Cmd { get { return _cmd; } }
  8885. private string _sn;
  8886. public string SN { get { return _sn; } }
  8887. private List<StepProcess> _stepProcesses;
  8888. public List<StepProcess> StepProcessesList { get { return _stepProcesses; } }
  8889. private bool _newStep;
  8890. public bool NewStep { get { return _newStep; } }
  8891. private int _stepIndex;
  8892. public int StepIndex { get { return _stepIndex; } }
  8893. private string _mesg;
  8894. public string Mesg { get { return _mesg; } }
  8895. private bool _compareResult;
  8896. public bool CompareResult { get { return _compareResult; } }
  8897. private string _compareResultString;
  8898. public string CompareResultString { get { return _compareResultString; } }
  8899. private long _time;
  8900. public long Time { get { return _time; } }
  8901. private int _num;
  8902. public long Num { get { return _num; } }
  8903. private long _cnt;
  8904. public long Cnt { get { return _cnt; } }
  8905. public RunEventArgs(string sn, List<StepProcess> list, bool newstep = false)
  8906. {
  8907. this._cmd = 0;
  8908. this._sn = sn;
  8909. this._stepProcesses = list;
  8910. this._newStep = newstep;
  8911. }
  8912. public RunEventArgs(int stepIndex)
  8913. {
  8914. this._cmd = 1;
  8915. this._stepIndex = stepIndex;
  8916. }
  8917. public RunEventArgs(int stepIndex, string mesg)
  8918. {
  8919. this._cmd = 2;
  8920. this._stepIndex = stepIndex;
  8921. _mesg = mesg;
  8922. }
  8923. public RunEventArgs(int cmd, bool rel, int cnt)
  8924. {
  8925. this._cmd = cmd;
  8926. this._compareResult = rel;
  8927. this._cnt = cnt;
  8928. }
  8929. public RunEventArgs(int cmd, bool rel, int cnt, string rel_str)
  8930. {
  8931. this._cmd = cmd;
  8932. this._compareResult = rel;
  8933. this._cnt = cnt;
  8934. this._compareResultString = rel_str;
  8935. }
  8936. public RunEventArgs(long time )
  8937. {
  8938. this._cmd = 7;
  8939. this._time = time;
  8940. }
  8941. public RunEventArgs(long time, int num)
  8942. {
  8943. this._cmd = 8;
  8944. this._time = time;
  8945. this._num = num;
  8946. }
  8947. private int _picIndex;
  8948. public int PicIndex { get { return _picIndex; } }
  8949. private HObject _pic;
  8950. public HObject Pic { get { return _pic; } }
  8951. public RunEventArgs(int index, HObject pic)
  8952. {
  8953. this._cmd = 6;
  8954. this._picIndex = index;
  8955. this._pic = pic.Clone();
  8956. }
  8957. private bool _over;
  8958. public bool Over { get { return _over; } }
  8959. public RunEventArgs(bool ov)
  8960. {
  8961. this._cmd = 10;
  8962. this._over = ov;
  8963. }
  8964. //测厚显示
  8965. private List<double> _value;
  8966. public List<double> Value { get { return _value; } }
  8967. private double _value_up;
  8968. public double Value_up { get { return _value_up; } }
  8969. private double _value_low;
  8970. public double Value_low { get { return _value_low; } }
  8971. public RunEventArgs(int cmd, List<double> val, double up, double low)
  8972. {
  8973. this._cmd = cmd;
  8974. this._value = val;
  8975. this._value_up = up;
  8976. this._value_low = low;
  8977. }
  8978. //新流程数据显示
  8979. private double _value_ave;
  8980. public double Value_ave { get { return _value_ave; } }
  8981. private int _processSts;
  8982. public int ProcessSts { get { return _processSts; } }
  8983. private bool _processType;
  8984. public bool ProcessType { get { return _processType; } }
  8985. public RunEventArgs(int stepIndex, string mesg, List<double> val, double rel_val, double max, double min, int proRel, bool type)
  8986. {
  8987. this._cmd = 30;
  8988. this._stepIndex = stepIndex;
  8989. this._mesg = mesg;
  8990. this._value = val;
  8991. this._value_ave = rel_val;
  8992. this._value_up = max;
  8993. this._value_low = min;
  8994. this._processSts = proRel;
  8995. this._processType = type;
  8996. }
  8997. public RunEventArgs(int stepIndex, string mesg, int proRel, bool type)
  8998. {
  8999. this._cmd = 31;
  9000. this._stepIndex = stepIndex;
  9001. this._mesg = mesg;
  9002. this._processSts = proRel;
  9003. this._processType = type;
  9004. }
  9005. }
  9006. /// <summary>
  9007. /// 显图事件
  9008. /// </summary>
  9009. public class ImgEventArgs : EventArgs
  9010. {
  9011. private Bitmap[] _bmps;
  9012. public Bitmap[] Bitmaps { get { return _bmps; } }
  9013. private Mat[] _bmps_cut;
  9014. public Mat[] Bmps_cut { get { return _bmps_cut; } }
  9015. private double _x;
  9016. public double X { get { return _x; } }
  9017. private double _y;
  9018. public double Y { get { return _y; } }
  9019. private string _name;
  9020. public string Name { get { return _name; } }
  9021. private List<Dictionary<int, List<string>[]>> _info;
  9022. public List<Dictionary<int, List<string>[]>> Info
  9023. {
  9024. get { return _info; }
  9025. }
  9026. public ImgEventArgs(Bitmap[] bmps, Mat[] bmps_cut, double Xmm, double Ymm, List<Dictionary<int, List<string>[]>> info)
  9027. {
  9028. this._bmps = new Bitmap[bmps.Length];
  9029. for (int i = 0; i < bmps.Length; i++)
  9030. {
  9031. this._bmps[i] = (Bitmap)bmps[i].Clone();
  9032. }
  9033. this._bmps_cut = new Mat[bmps_cut.Length];
  9034. for (int i = 0; i < bmps_cut.Length; i++)
  9035. {
  9036. this._bmps_cut[i] = bmps_cut[i].Clone();
  9037. }
  9038. this._x = Xmm;
  9039. this._y = Ymm;
  9040. this._info = info;
  9041. }
  9042. public ImgEventArgs(Mat bmps_cut, string name)
  9043. {
  9044. this._bmps = new Bitmap[1];
  9045. this._bmps[0] = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(bmps_cut);
  9046. this._bmps_cut = null;
  9047. //this._bmps_cut = new Mat[1];
  9048. //this._bmps_cut[0] = bmps_cut.Clone();
  9049. this._x = 0;
  9050. this._y = 0;
  9051. this._info = null;
  9052. this._name = name;
  9053. }
  9054. }
  9055. /// <summary>
  9056. /// 主窗体事件
  9057. /// </summary>
  9058. public class MainEventArgs : EventArgs
  9059. {
  9060. private string _tag;
  9061. public string Tag { get { return _tag; } }
  9062. private string _message;
  9063. public string Message { get { return _message; } }
  9064. private int _showIndex;
  9065. public int ShowIndex { get { return _showIndex; } }
  9066. private WarningEnum _warning;
  9067. public WarningEnum Warning { get { return _warning; } }
  9068. public MainEventArgs(int index)
  9069. {
  9070. this._showIndex = index;
  9071. }
  9072. public MainEventArgs(int index, string message)
  9073. {
  9074. this._message = message;
  9075. this._showIndex = index;
  9076. }
  9077. public MainEventArgs(string tag, string message, WarningEnum warning = WarningEnum.Normal)
  9078. {
  9079. this._tag = tag;
  9080. this._message = message;
  9081. this._showIndex = 0;
  9082. this._warning = warning;
  9083. }
  9084. }
  9085. /// <summary>
  9086. /// 初始化事件
  9087. /// </summary>
  9088. public class InitEventArgs : EventArgs
  9089. {
  9090. private string _message;
  9091. public string Message { get { return _message; } }
  9092. private bool _isInitialized;
  9093. public bool IsInitialized { get { return _isInitialized; } }
  9094. public InitEventArgs()
  9095. {
  9096. }
  9097. public InitEventArgs(string message, bool isInitialized = false)
  9098. {
  9099. this._message = message;
  9100. this._isInitialized = isInitialized;
  9101. }
  9102. }
  9103. #endregion
  9104. }