版博士V2.0程序
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

10792 Zeilen
617 KiB

  1. using BarTenderPrint;
  2. using CCWin.SkinClass;
  3. using CCWin.Win32;
  4. using CCWin.Win32.Com;
  5. using CCWin.Win32.Const;
  6. using HalconDotNet;
  7. using HZH_Controls;
  8. using HZH_Controls.Forms;
  9. using ImageToolKits;
  10. using MaiMuAOI.ImageProcessing;
  11. using MaiMuAOI.SysUI.ProcessStep.Prop;
  12. using MaiMuAOI.SysUI.ProductAndStep;
  13. using MaiMuControl.Device;
  14. using MaiMuControl.Device.AxisDev;
  15. using MaiMuControl.Device.AxisDev.Advantech;
  16. using MaiMuControl.Device.AxisDev.PMS;
  17. using MaiMuControl.Device.CamDev;
  18. using MaiMuControl.Device.IOCardDev;
  19. using MaiMuControl.Device.IOCardDev.Advantech;
  20. using MaiMuControl.Device.LightDev;
  21. using MaiMuControl.Device.LightDev.CST;
  22. using MaiMuControl.Device.LightDev.Rsee;
  23. using MaiMuControl.Device.SenSorDev;
  24. using MaiMuControl.Device.SenSorDev.HeightSensor;
  25. using MaiMuControl.Device.SenSorDev.TensionSensor;
  26. using MaiMuControl.SysStatusMgr.CloudMgr;
  27. using MaiMuControl.SysStatusMgr.MqttMgr;
  28. using MaiMuControl.SysStatusMgr.StatusMgr;
  29. using MaiMuControl.SysStatusMgr.UserMgr;
  30. using MaiMuControl.Utils;
  31. using Models;
  32. using Newtonsoft.Json;
  33. using Newtonsoft.Json.Linq;
  34. using OpenCvSharp;
  35. using OpenCvSharp.Flann;
  36. using ProductionControl;
  37. using ProductionControl.UI;
  38. using ProductionControl.UIExtend;
  39. using Service;
  40. using SqlSugar;
  41. using System;
  42. using System.Collections;
  43. using System.Collections.Generic;
  44. using System.Data;
  45. using System.Diagnostics;
  46. using System.Drawing;
  47. using System.Drawing.Imaging;
  48. using System.IO;
  49. using System.Linq;
  50. using System.Reflection;
  51. using System.Runtime.Remoting.Lifetime;
  52. using System.Security.Cryptography;
  53. using System.Text;
  54. using System.Threading;
  55. using System.Threading.Tasks;
  56. using System.Web;
  57. using System.Windows.Forms;
  58. using System.Xml.Linq;
  59. using ToolKits.Disk;
  60. using ToolKits.EnumTool;
  61. using ToolKits.Http;
  62. using ToolKits.mAPI;
  63. using Yolo5;
  64. using static MaiMuAOI.ImageProcessing.DefectLib;
  65. using static MaiMuAOI.ImageProcessing.SizeLib;
  66. using static MaiMuAOI.SysCtrl.SysMgr;
  67. using static MaiMuControl.SysStatusMgr.MqttMgr.MyMqttClient;
  68. using static System.Net.Mime.MediaTypeNames;
  69. using static System.Windows.Forms.VisualStyles.VisualStyleElement;
  70. namespace MaiMuAOI.SysCtrl
  71. {
  72. /// <summary>
  73. /// 主系统控制
  74. /// </summary>
  75. public class SysMgr
  76. {
  77. #region singleton实例化
  78. private static SysMgr _instance;
  79. private static readonly object _lock = new object();
  80. public static SysMgr Instance
  81. {
  82. get
  83. {
  84. if (_instance == null)
  85. {
  86. lock (_lock)
  87. {
  88. if (_instance == null)
  89. {
  90. _instance = new SysMgr();
  91. }
  92. }
  93. }
  94. return _instance;
  95. }
  96. }
  97. #endregion
  98. public CameraEnumType SysUseCamFront = CameraEnumType.MVSCamera_CC;
  99. public CameraEnumType SysUseCamBack = CameraEnumType.MVSCamera_GENTL;
  100. public LightDevNameEnum SysUseLight = LightDevNameEnum.CST;
  101. //主流程
  102. private Thread _mainThread;
  103. private CancellationTokenSource _cts;
  104. /// <summary>
  105. /// 流程序号
  106. /// </summary>
  107. private int CurrProcessIndex = 0;
  108. /// <summary>
  109. /// 当前点位号
  110. /// </summary>
  111. private int CurrPoinntCount = 0;
  112. /// <summary>
  113. /// 总计时
  114. /// </summary>
  115. private Stopwatch stopWatch;
  116. //运动曲线 默认T型 0更快
  117. public int MotionST = 0;
  118. public double DefaultSpeed = 200;
  119. //系统状态
  120. private StatusMgr statusMgr;
  121. public StatusMgr StatusMgr { get { return statusMgr; } }
  122. //用户管理
  123. private UserMgr userMgr;
  124. public UserMgr UserMgr { get { return userMgr; } }
  125. //系统配置管理
  126. private ConfMgr confMgr;
  127. //web服务器
  128. private WebService webService;
  129. //局域网云端
  130. private bool init_Cloud;
  131. private CloudMgr cloudMgr;
  132. private int DailyOutput;
  133. //产品数据服务器
  134. private MyMqttHostServer myMqttHostServer;
  135. private MyMqttClient myMqttClient;
  136. //产品列表
  137. private List<string> productCodeList = new List<string>();
  138. public List<string> ProductCodeList { get { return productCodeList; } }
  139. //产品ID列表
  140. private List<int> productIdList = new List<int>();
  141. public List<int> ProductIdList { get { return productIdList; } }
  142. //近期SN列表
  143. private List<string> productSNList = new List<string>();
  144. public List<string> ProductSNList { get { return productSNList; } }
  145. Service.ProductService PdtService;
  146. Service.OrderService OrderService;
  147. Service.ClassesService svcClasses;
  148. //可用步骤
  149. public static Dictionary<string, string> dicDevType = new Dictionary<string, string>();
  150. //2023-12-20 新流程步骤
  151. public static Dictionary<string, string> ProcessType = new Dictionary<string, string>();
  152. //图像处理
  153. private DefectLib defectLib;
  154. public DefectLib DefectLib { get { return defectLib; } }
  155. private SizeLib sizeLib;
  156. public SizeLib SizeLib { get { return sizeLib; } }
  157. private int SizeNGCnt;
  158. //流程处理
  159. private ForLib forLib;
  160. private IFLib ifLib;
  161. /// <summary>
  162. /// 当前产品
  163. /// </summary>
  164. private Models.Product CurrProductModel = null;
  165. /// <summary>
  166. /// 当前料号
  167. /// </summary>
  168. private Order order = new Order();
  169. //产品-厚度base校正点位索引
  170. private int ProductPT_HeightBaseNum = 0;
  171. //线宽,张力,厚度,PT
  172. private List<double> lstTension = new List<double>();
  173. private List<double> lstHeight = new List<double>();
  174. private List<double> lstHeightBase = new List<double>();
  175. private List<double> lstLineWidth = new List<double>();
  176. private List<double> lstPT = new List<double>();
  177. private List<double> lstTestData = new List<double>();
  178. //系统判断是否是新流程
  179. private bool IsNewStepProcessVel;
  180. //当前测试结果
  181. private int CurrStepResult = 0;
  182. //当前厚度基准是否完成
  183. private bool IsCurrHeightBase = false;
  184. //双控按钮信号
  185. private bool IsGetStartSig = false;
  186. //自动聚焦参数
  187. private bool IsAutoFocus { get; set; }
  188. private double FocusStep { get; set; }
  189. private double DirStep { get; set; }
  190. private int DirWaitTime { get; set; }
  191. private int FocusTimeOut { get; set; }
  192. //缺陷循环参数
  193. private double Left_X = 0;
  194. private double Left_Y = 0;
  195. private int X_For = 0;
  196. private int Y_For = 0;
  197. private int X_For_Index = 0;
  198. private int Y_For_Index = 0;
  199. //图纸选点参数
  200. private int[] CurrAdaqter = new int[9];
  201. //image.save保存锁,防止多线程报错
  202. private object ImageSaveObj = new object();
  203. //2024-03-12 加入打印列表
  204. private List<PrintInfo> CurrPrintInfos = new List<PrintInfo>();
  205. //2024-03-26 加入整体工单打印列表
  206. private List<PrintInfo> CurrOrderPrintInfos = new List<PrintInfo>();
  207. //2024-03-26 加入尺寸和缺陷禁用快捷键
  208. private bool SizeEnable;
  209. private bool DefectEnable;
  210. //2024-03-26 加入单号检测总数,ok数,ng数
  211. private int TotalCnt = 0;
  212. private int CurrDefectIndex = 0;
  213. private List<Order> CurrDefectOrders = new List<Order>();
  214. #region 图像显示列表
  215. private class scannerGBmpLoc
  216. {
  217. public scannerGBmpLoc(Mat mat, double xmm, double ymm)
  218. {
  219. bmp = mat;
  220. Xmm = xmm;
  221. Ymm = ymm;
  222. }
  223. public Mat bmp { get; private set; }
  224. public double Xmm { get; private set; }
  225. public double Ymm { get; private set; }
  226. }
  227. private class scannerCBmpLoc
  228. {
  229. public scannerCBmpLoc(string path, double posX, double posY)
  230. {
  231. Path = path;
  232. PosX = posX;
  233. PosY = posY;
  234. }
  235. public scannerCBmpLoc(HObject himg, double posX, double posY)
  236. {
  237. Himage = himg;
  238. PosX = posX;
  239. PosY = posY;
  240. }
  241. public HObject Himage { get; private set; }
  242. public string Path { get; private set; }
  243. public double PosX { get; private set; }
  244. public double PosY { get; private set; }
  245. }
  246. private Queue<scannerGBmpLoc> scannerGBmpQueue = new Queue<scannerGBmpLoc>();
  247. private Queue<scannerCBmpLoc> scannerCBmpQueue = new Queue<scannerCBmpLoc>();
  248. /// <summary>
  249. /// 比对失败的图片
  250. /// </summary>
  251. private List<Bitmap> lstCompareFailZoomImage = new List<Bitmap>();
  252. /// <summary>
  253. /// --333输出变量供后面多个777使用
  254. /// </summary>
  255. public HObject contoursAffineTrans1_Out;
  256. /// <summary>
  257. /// 对比引索
  258. /// </summary>
  259. private int compBmpIndex = 0;//比对777图的索引
  260. /// <summary>
  261. /// 对比张数
  262. /// </summary>
  263. private int compBmpNum = 0;//比对张数
  264. /// <summary>
  265. /// 缺陷处理图片张数
  266. /// </summary>
  267. private int defectBmpNum = 0;
  268. /// <summary>
  269. /// 缺陷处理结果
  270. /// </summary>
  271. private int defectBmpNumResult = 0;
  272. /// <summary>
  273. /// 缺陷总不良数
  274. /// </summary>
  275. private int AllDefectCount = 0;
  276. #endregion
  277. private SysMgr()
  278. {
  279. _isInit = false;
  280. _isRuning = false;
  281. statusMgr = StatusMgr.Instance;
  282. confMgr = ConfMgr.Instance;
  283. //设置本机为主机数据库
  284. statusMgr.SetMySqlIPaddr("127.0.0.1");
  285. userMgr = new UserMgr(statusMgr.MySqlIP);
  286. Service.InitDB.ConnectionString = confMgr.DBConStr;
  287. PdtService = new Service.ProductService();
  288. OrderService = new OrderService();
  289. webService = new WebService();
  290. svcClasses = new Service.ClassesService();
  291. init_Cloud = false;
  292. cloudMgr = new CloudMgr();
  293. DailyOutput = 0;
  294. myMqttHostServer = new MyMqttHostServer();
  295. myMqttClient = new MyMqttClient();
  296. scannerGBmpQueue = new Queue<scannerGBmpLoc>();
  297. scannerCBmpQueue = new Queue<scannerCBmpLoc>();
  298. lstCompareFailZoomImage = new List<Bitmap>();
  299. MotionST = 0;
  300. DefaultSpeed = 200;
  301. _cts = new CancellationTokenSource();
  302. SizeEnable = true;
  303. DefectEnable = true;
  304. IsNewStepProcessVel = false;
  305. InitDevDic();
  306. }
  307. #region 日志报警
  308. /// <summary>
  309. /// 初始化记录报警和显示
  310. /// </summary>
  311. /// <param name="tag">标头</param>
  312. /// <param name="msg">内容</param>
  313. /// <param name="warning">报警状态</param>
  314. private void InitLog(string msg, string tag = "初始化", WarningEnum warning = WarningEnum.Normal)
  315. {
  316. OnInitRuning(new InitEventArgs(msg));
  317. statusMgr.GotoWarning(warning, tag, msg);
  318. }
  319. /// <summary>
  320. /// 记录报警和显示
  321. /// </summary>
  322. /// <param name="tag">标头</param>
  323. /// <param name="msg">内容</param>
  324. /// <param name="warning">报警状态</param>
  325. private void Log(string tag, string msg, WarningEnum warning = WarningEnum.Normal)
  326. {
  327. OnMainRuning(new MainEventArgs(tag, msg, warning));
  328. statusMgr.GotoWarning(warning, tag, msg);
  329. //开启云端
  330. if((init_Cloud)&&(warning != WarningEnum.Normal))
  331. {
  332. //上传报警状态和信息
  333. string statusStr = warning == WarningEnum.Normal ? "正常" : warning == WarningEnum.Low ? "警告":"系统报警" ;
  334. cloudMgr.SendTopic("device/attributes", $"{{\"status\": \"{statusStr}\", \"alm\": \"{tag}-{msg}\", " +
  335. $"\"name\": \"{confMgr.SysConfigParams.CloudThisName}\", \"DailyOutput\": \"{DailyOutput}\"}}");
  336. }
  337. }
  338. #endregion
  339. #region 本地云上传
  340. /// <summary>
  341. /// 上传当日产量
  342. /// </summary>
  343. private void SendDailyOutput()
  344. {
  345. //开启云端
  346. if (init_Cloud)
  347. {
  348. try
  349. {
  350. if(!cloudMgr.SendTopic("device/attributes", $"{{ \"DailyOutput\": \"{DailyOutput}\"}}"))
  351. Log("云端", $"上传失败", WarningEnum.Low);
  352. }
  353. catch (Exception e)
  354. {
  355. Log("云端", $"上传失败:{e.Message}", WarningEnum.Low);
  356. }
  357. }
  358. }
  359. /// <summary>
  360. /// 上传正常状态
  361. /// </summary>
  362. public void SendStatus()
  363. {
  364. //开启云端
  365. if (init_Cloud)
  366. {
  367. //上传报警状态和信息
  368. string statusStr = "正常";
  369. switch(StatusMgr.Status)
  370. {
  371. case SystemStsEnum.Manual:
  372. statusStr = "人工操作";
  373. break;
  374. case SystemStsEnum.Standby:
  375. statusStr = "正常待机";
  376. break;
  377. case SystemStsEnum.Initial:
  378. statusStr = "初始化";
  379. break;
  380. case SystemStsEnum.Auto:
  381. statusStr = "自动运行";
  382. break;
  383. case SystemStsEnum.Pause:
  384. statusStr = "自动暂停";
  385. break;
  386. case SystemStsEnum.SetParams:
  387. statusStr = "参数设置";
  388. break;
  389. case SystemStsEnum.Debug:
  390. statusStr = "调试";
  391. break;
  392. case SystemStsEnum.Warning:
  393. statusStr = "系统报警";
  394. break;
  395. case SystemStsEnum.Bootload:
  396. statusStr = "Bootload";
  397. break;
  398. default:
  399. statusStr = "未知";
  400. break;
  401. }
  402. try
  403. {
  404. if(!cloudMgr.SendTopic("device/attributes", $"{{\"status\": \"{statusStr}\", \"alm\": \"无报警信息\", " +
  405. $"\"name\": \"{confMgr.SysConfigParams.CloudThisName}\", \"DailyOutput\": \"{DailyOutput}\"}}"))
  406. Log("云端", $"上传失败", WarningEnum.Low);
  407. }
  408. catch (Exception e)
  409. {
  410. Log("云端", $"上传失败:{e.Message}", WarningEnum.Low);
  411. }
  412. }
  413. }
  414. #endregion
  415. #region 产品服务器
  416. public bool InitPdtService()
  417. {
  418. if (confMgr.SysConfigParams.OpenPdtServer)
  419. {
  420. try
  421. {
  422. if (confMgr.SysConfigParams.IsPdtServer)
  423. {
  424. myMqttHostServer.StartAsync(confMgr.SysConfigParams.PdtServerPort);
  425. Log("产品服务", "产品服务器打开");
  426. //自发自测
  427. //myMqttClient.MqttClientStart(confMgr.SysConfigParams.PdtServerIP, confMgr.SysConfigParams.PdtServerPort,
  428. // "admin", "123456", confMgr.SysConfigParams.CloudThisName, "pdtinfo");
  429. //myMqttClient.RecvRuning += Recv_Process;
  430. //Log("产品服务", "产品客户端打开");
  431. }
  432. else
  433. {
  434. myMqttClient.MqttClientStart(confMgr.SysConfigParams.PdtServerIP, confMgr.SysConfigParams.PdtServerPort,
  435. "admin", "123456", confMgr.SysConfigParams.CloudThisName, "pdtinfo");
  436. myMqttClient.RecvRuning += Recv_Process;
  437. Log("产品服务", "产品客户端打开");
  438. }
  439. return true;
  440. }
  441. catch (Exception e)
  442. {
  443. Log("产品服务", "产品服务器或客户端打开失败!", WarningEnum.Low);
  444. return false;
  445. }
  446. }
  447. return true;
  448. }
  449. //产品数据解析
  450. private int pdtID = -1;
  451. private List<byte[]> FileDataList = new List<byte[]>();//文件数据
  452. private byte[] Combine(params byte[][] arrays)
  453. {
  454. byte[] rv = new byte[arrays.Sum(a => a.Length)];
  455. int offset = 0;
  456. foreach (byte[] array in arrays)
  457. {
  458. System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
  459. offset += array.Length;
  460. }
  461. return rv;
  462. }
  463. private void Recv_Process(object sender, RecvEventArgs e)
  464. {
  465. Thread t = new Thread(() =>
  466. {
  467. if (e.Topic == "TopicToServer")
  468. {
  469. if (pdtID >= 0)
  470. {
  471. Log("产品服务", "开始接收产品文件");
  472. //接收文件
  473. JObject json = JObject.Parse(e.Payload);
  474. string filename = json.Value<string>("FileName");
  475. byte[] datas = Convert.FromBase64String(json.Value<string>("data"));
  476. int index = int.Parse(json.Value<string>("index"));
  477. int packageNums = int.Parse(json.Value<string>("packageNums"));
  478. if (index == 0)
  479. FileDataList.Clear();
  480. FileDataList.Add(datas);
  481. if (index == (packageNums - 1))
  482. {
  483. byte[] alldatas = Combine(FileDataList.ToArray());
  484. //创建文件夹
  485. if (!Directory.Exists(ConfMgr.Instance.ProjectDir + $"\\{pdtID}\\"))
  486. {
  487. Directory.CreateDirectory(ConfMgr.Instance.ProjectDir + $"\\{pdtID}\\");
  488. }
  489. //2、将byte[]数组保存成文件
  490. File.WriteAllBytes(ConfMgr.Instance.ProjectDir + $"\\{pdtID}\\" + filename, alldatas);
  491. Log("产品服务", $"保存文件:{ConfMgr.Instance.ProjectDir + $"\\{pdtID}\\" + filename}");
  492. }
  493. }
  494. //else
  495. // Log("产品服务", "中断接收产品文件", WarningEnum.Low);
  496. }
  497. else if (e.Topic == "pdtinfo")
  498. {
  499. Log("产品服务", "开始接收产品数据");
  500. pdtID = -1;
  501. //解析产品数据
  502. Product pdt = JsonConvert.DeserializeObject<Product>(e.Payload);
  503. pdt.Id = 0;
  504. pdt.CompleteCount = 0;
  505. pdt.CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code;
  506. Models.Attachment attachmentFile = pdt.AttachmentList.FirstOrDefault(m => m.Type == 0);
  507. string fileName = attachmentFile.Name;
  508. string fileExtend = attachmentFile.ExtendName;
  509. string fileOnlyName = fileName.Substring(0, fileName.Length - fileExtend.Length);
  510. //判断是否有同样名称数据
  511. Product Havepdt = PdtService.GetModelNav(pdt.Code);
  512. if(Havepdt != null)
  513. {
  514. Log("产品服务", $"已存在料号:{pdt.Code}!", WarningEnum.Low);
  515. return;
  516. }
  517. try
  518. {
  519. bool result = PdtService.InsertNav(pdt);
  520. }
  521. catch (Exception ex)
  522. {
  523. //MyMqttService._recvGet = true;
  524. Log("产品服务", $"保存错误:{ex.Message}", WarningEnum.Low);
  525. return;
  526. }
  527. pdt = PdtService.GetModelNav(pdt.Code);
  528. attachmentFile = pdt.AttachmentList.FirstOrDefault(m => m.Type == 0);
  529. pdtID = pdt.Id;//获取新id
  530. if (attachmentFile != null)
  531. {
  532. attachmentFile.Type = 0;//图纸
  533. attachmentFile.NameTimestamp = $"{pdt.Id}\\{fileOnlyName}";
  534. attachmentFile.Name = fileName;
  535. attachmentFile.ExtendName = fileExtend;
  536. }
  537. else
  538. {
  539. pdt.AttachmentList.Add(new Models.Attachment()
  540. {
  541. TBName = "product",
  542. Type = 0,
  543. NameTimestamp = $"{pdt.Id}\\{fileOnlyName}",
  544. Name = fileName,
  545. ExtendName = fileExtend,
  546. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  547. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  548. });
  549. }
  550. if (!PdtService.UpdateNav(pdt))
  551. throw new Exception("保存文件失败!");
  552. //MyMqttService._recvGet = true;
  553. }
  554. Log("产品服务", "接收完成");
  555. });
  556. t.Start();
  557. }
  558. /// <summary>
  559. /// 发送产品数据
  560. /// </summary>
  561. /// <param name="model"></param>
  562. /// <returns></returns>
  563. public bool SendPdtData(Product model)
  564. {
  565. if(model == null)
  566. {
  567. MessageBox.Show("无产品数据!","错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  568. return false;
  569. }
  570. Models.Attachment attachmentFile = model.AttachmentList.FirstOrDefault(m => m.Type == 0);
  571. DialogResult dr = DialogResult.Cancel;
  572. if ((attachmentFile == null)|| (model.MapPath == null) || (string.IsNullOrEmpty(model.MapPath)))
  573. {
  574. dr = MessageBox.Show("无产品图纸数据,是否继续?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
  575. if (dr == DialogResult.Cancel)
  576. {
  577. return false;
  578. }
  579. }
  580. string sjson = JsonConvert.SerializeObject(model);
  581. bool rt = MyMqttService.PublishData("pdtinfo", sjson);
  582. if (!rt)
  583. {
  584. MessageBox.Show("发送失败,网络错误!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  585. return false;
  586. }
  587. //无法做到发送之后等待返回结果,因为多机台客户端无法同步返回
  588. //DateTime dt = DateTime.Now;
  589. //while (!MyMqttService._recvGet)
  590. //{
  591. // Thread.Sleep(5);
  592. // if ((DateTime.Now - dt).TotalSeconds > 10)
  593. // {
  594. // MessageBox.Show("发送接收失败,网络错误!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  595. // return false;
  596. // }
  597. //}
  598. Thread.Sleep(2000); //发送数据之后,等待2s发送文件
  599. if(dr == DialogResult.Cancel)
  600. {
  601. rt = MyMqttService.PublishFiles(ConfMgr.Instance.ProjectDir + $"\\{model.Id}\\");
  602. }
  603. if(!rt)
  604. {
  605. return false;
  606. }
  607. return true;
  608. }
  609. #endregion
  610. #region 硬件
  611. #region 硬件字段
  612. private AxisDev axisDev;
  613. /// <summary>
  614. /// 运动板卡
  615. /// </summary>
  616. public AxisDev AxisDev { get { return axisDev; } }
  617. private BoardCfgParams boardCfgParams;
  618. private HomeVelocityParams homeParamsX1;
  619. public HomeVelocityParams HomeParamsX1 { get { return homeParamsX1; } }
  620. private HomeVelocityParams homeParamsX2;
  621. public HomeVelocityParams HomeParamsX2 { get { return homeParamsX2; } }
  622. private HomeVelocityParams homeParamsY;
  623. public HomeVelocityParams HomeParamsY { get { return homeParamsY; } }
  624. private HomeVelocityParams homeParamsZ;
  625. public HomeVelocityParams HomeParamsZ { get { return homeParamsZ; } }
  626. private IOCardDev ioCardDev;
  627. /// <summary>
  628. /// io控制卡
  629. /// </summary>
  630. public IOCardDev IOCardDev { get { return ioCardDev; } }
  631. private LightDev lightDev;
  632. /// <summary>
  633. /// 光源控制
  634. /// </summary>
  635. public LightDev LightDev { get { return lightDev; } }
  636. public string LightName { get { return "Light"; } }
  637. public int LightChCount = 6;//美尚4通道,其他6通道
  638. private CamDev camDevFront;
  639. /// <summary>
  640. /// 前部相机控制
  641. /// </summary>
  642. public CamDev CamDevFront { get { return camDevFront; } }
  643. private CamDev camDevBack;
  644. /// <summary>
  645. /// 后部相机控制
  646. /// </summary>
  647. public CamDev CamDevBack { get { return camDevBack; } }
  648. private ValueSensorDev tensionDev;
  649. /// <summary>
  650. /// 张力传感器
  651. /// </summary>
  652. public ValueSensorDev TensionDev { get { return tensionDev; } }
  653. private ValueSensorDev thicknessDev;
  654. /// <summary>
  655. /// 厚度传感器
  656. /// </summary>
  657. public ValueSensorDev ThicknessDev { get { return thicknessDev; } }
  658. private AxisDev lensMotorDev;
  659. /// <summary>
  660. /// 镜头电机
  661. /// </summary>
  662. public AxisDev LensMotorDev { get { return lensMotorDev; } }
  663. private PrintControl printControl;
  664. /// <summary>
  665. /// 打印机模块
  666. /// </summary>
  667. public PrintControl PrintControl { get { return printControl; } }
  668. #endregion
  669. #region 初始化和基本电机IO操作
  670. private void InitDev()
  671. {
  672. axisDev = new AdvantechMotion();
  673. ioCardDev = new AdvantechIO();
  674. if(SysUseLight == LightDevNameEnum.CST)
  675. lightDev = new CSTLight(LightName, LightChCount);
  676. else
  677. lightDev = new RseeLight(SysUseLight, LightName);
  678. tensionDev = new TensionSensor();
  679. lensMotorDev = new PmsMotion();
  680. thicknessDev = new HeightSensorDev();
  681. camDevFront = new CamDev(SysUseCamFront, confMgr.SysConfigParams.FrontCamName, confMgr.SysConfigParams.FrontCamCfgPath);
  682. camDevBack = new CamDev(SysUseCamBack, confMgr.SysConfigParams.BackCamName, confMgr.SysConfigParams.BackCamCfgPath);
  683. defectLib = new DefectLib();
  684. sizeLib = new SizeLib();
  685. forLib = new ForLib();
  686. ifLib = new IFLib();
  687. boardCfgParams= new BoardCfgParams();
  688. boardCfgParams.DevEmgLogic = 1;
  689. }
  690. /// <summary>
  691. /// 初始化硬件
  692. /// </summary>
  693. /// <returns></returns>
  694. private bool InitAllDev()
  695. {
  696. bool ret = false;
  697. InitDev();
  698. //打印机模块初始化
  699. InitLog("打印机模块初始化...");
  700. try
  701. {
  702. printControl = new PrintControl();
  703. InitLog("初始化打印机模块成功!");
  704. }
  705. catch (Exception ex)
  706. {
  707. printControl = null;
  708. InitLog($"初始化打印机模块失败! {ex.Message}");
  709. }
  710. //IO初始化
  711. InitLog("IO板卡初始化...");
  712. if (ioCardDev.InitBoard(MaiMuControl.Device.IOBordType.Advantech) < 0)
  713. {
  714. InitLog("IO板卡初始化失败!", "初始化", WarningEnum.High);
  715. return ret;
  716. }
  717. if(ioCardDev.OpenBoard(confMgr.SysConfigParams.IODevName, confMgr.SysConfigParams.IOCfgPath)<0)
  718. {
  719. InitLog("打开IO板卡失败!", "初始化", WarningEnum.High);
  720. return ret;
  721. }
  722. if (ioCardDev.ResetAllDO()<0)
  723. {
  724. InitLog("IO Reset失败!", "初始化", WarningEnum.High);
  725. return ret;
  726. }
  727. InitLog("初始化IO板卡成功!");
  728. //电机初始化
  729. InitLog("运动控制板卡初始化...");
  730. if(axisDev.InitBoard()<0)
  731. {
  732. InitLog("运动控制板卡初始化失败!", "初始化", WarningEnum.High);
  733. return ret;
  734. }
  735. if (axisDev.OpenBoard(0, confMgr.SysConfigParams.MotionCfgPath) < 0)
  736. {
  737. InitLog("打开运动控制板卡失败!", "初始化", WarningEnum.High);
  738. return ret;
  739. }
  740. //if (axisDev.LoadCfgFile(0, confMgr.SysConfigParams.MotionCfgPath) < 0)
  741. //{
  742. // InitLog("载入运动控制板卡参数失败2!", "初始化", WarningEnum.High);
  743. // return ret;
  744. //}
  745. if (axisDev.LoadBoardParams(0, boardCfgParams) < 0)
  746. {
  747. InitLog("载入运动控制板卡参数失败1!", "初始化", WarningEnum.High);
  748. return ret;
  749. }
  750. //光源初始化
  751. InitLog("光源控制器初始化...");
  752. int com_num = int.Parse(confMgr.SysConfigParams.LightCom.Remove(0, 3));
  753. if (lightDev.InitDev(com_num, confMgr.SysConfigParams.LightComBaud) < 0)
  754. {
  755. InitLog("光源控制器初始化失败!", "初始化", WarningEnum.High);
  756. return ret;
  757. }
  758. InitLog("初始化光源控制器成功!");
  759. //关闭光源
  760. for (int i = 0; i < LightChCount; i++)
  761. {
  762. lightDev.CloseLight(i + 1);
  763. }
  764. //张力传感器初始化
  765. InitLog("张力传感器初始化...");
  766. if (tensionDev.OpenDevByCom(confMgr.SysConfigParams.TensionCom, confMgr.SysConfigParams.TensionComBaud) < 0)
  767. {
  768. InitLog("张力传感器初始化失败!", "初始化", WarningEnum.High);
  769. return ret;
  770. }
  771. InitLog("初始化张力传感器成功!");
  772. //镜头电机初始化
  773. InitLog("镜头电机初始化...");
  774. lensMotorDev.InitBoard();
  775. if (lensMotorDev.OpenBoardByCom(confMgr.SysConfigParams.LensMotorCom, confMgr.SysConfigParams.LensMotorComBaud) < 0)
  776. {
  777. InitLog("镜头电机初始化失败!", "初始化", WarningEnum.High);
  778. return ret;
  779. }
  780. InitLog("初始化镜头电机成功!");
  781. //测厚传感器初始化
  782. InitLog("测厚传感器初始化...");
  783. if (thicknessDev.OpenDevByTcp(confMgr.SysConfigParams.ThicknessIP, confMgr.SysConfigParams.ThicknessPort) < 0)
  784. {
  785. InitLog("测厚传感器初始化失败!", "初始化", WarningEnum.High);
  786. return ret;
  787. }
  788. InitLog("初始化测厚传感器成功!");
  789. //前部相机初始化
  790. InitLog("前部相机初始化...");
  791. if(!camDevFront.InitCamera())
  792. {
  793. InitLog("前部相机初始化失败!", "初始化", WarningEnum.High);
  794. return ret;
  795. }
  796. if (!camDevFront.OpenCamera())
  797. {
  798. InitLog("前部相机打开失败!", "初始化", WarningEnum.High);
  799. return ret;
  800. }
  801. InitLog("初始化前部相机成功!");
  802. //后部相机初始化
  803. InitLog("后部相机初始化...");
  804. if (!camDevBack.InitCamera())
  805. {
  806. InitLog("后部相机初始化失败!", "初始化", WarningEnum.High);
  807. return ret;
  808. }
  809. if (!camDevBack.OpenCamera())
  810. {
  811. InitLog("后部相机打开失败!", "初始化", WarningEnum.High);
  812. return ret;
  813. }
  814. InitLog("初始化后部相机成功!");
  815. ret = true;
  816. return ret;
  817. }
  818. /// <summary>
  819. /// 读取硬件配置
  820. /// </summary>
  821. private bool LoadDevConfig()
  822. {
  823. homeParamsX1 = axisDev.ReadAxisCfg(confMgr.DevConfigPath, (int)AxisName.Axis0);
  824. homeParamsX2 = axisDev.ReadAxisCfg(confMgr.DevConfigPath, (int)AxisName.Axis1);
  825. homeParamsY = axisDev.ReadAxisCfg(confMgr.DevConfigPath, (int)AxisName.Axis2);
  826. homeParamsZ = axisDev.ReadAxisCfg(confMgr.DevConfigPath, (int)AxisName.Axis3);
  827. LightParams lightParams = new LightParams(LightName, LightChCount);
  828. //LightChCount = 6;
  829. //lightParams.DevName = LightName;
  830. lightParams.ComName = confMgr.SysConfigParams.LightCom;
  831. lightParams.Buad = confMgr.SysConfigParams.LightComBaud;
  832. //lightParams.ChCount = LightChCount;
  833. lightDev.WriteCfgInfo(confMgr.DevConfigPath, lightParams);
  834. DevParams devParams = new DevParams("tensionDev", confMgr.SysConfigParams.TensionCom,
  835. int.Parse(confMgr.SysConfigParams.TensionCom.Remove(0, 3)), confMgr.SysConfigParams.TensionComBaud);
  836. tensionDev.WriteDevCfg(confMgr.DevConfigPath, 0, devParams);
  837. devParams = new DevParams("thicknessDev", confMgr.SysConfigParams.ThicknessIP,
  838. confMgr.SysConfigParams.ThicknessPort);
  839. thicknessDev.WriteDevCfg(confMgr.DevConfigPath, 0, devParams);
  840. //ioCardDev.ReadCfgInfo(confMgr.DevConfigPath, "IO_1");
  841. if ((homeParamsZ == null) || (homeParamsX1 == null) || (homeParamsX2 == null) || (homeParamsY == null)||
  842. !homeParamsZ.IsValid() || !homeParamsX1.IsValid() || !homeParamsX2.IsValid() || !homeParamsY.IsValid())
  843. return false;
  844. return true;
  845. }
  846. /// <summary>
  847. /// 急停所有电机
  848. /// </summary>
  849. private void AxisAllImmediateStop()
  850. {
  851. axisDev.ImmediateStop((int)AxisName.Axis0);
  852. axisDev.ImmediateStop((int)AxisName.Axis1);
  853. axisDev.ImmediateStop((int)AxisName.Axis2);
  854. axisDev.ImmediateStop((int)AxisName.Axis3);
  855. }
  856. /// <summary>
  857. /// 减速停止
  858. /// </summary>
  859. private void AxisDStop()
  860. {
  861. axisDev.DecelStop((int)AxisName.Axis0);
  862. axisDev.DecelStop((int)AxisName.Axis1);
  863. axisDev.DecelStop((int)AxisName.Axis2);
  864. axisDev.DecelStop((int)AxisName.Axis3);
  865. }
  866. /// <summary>
  867. /// 获取脉冲对应的mm距离
  868. /// </summary>
  869. /// <param name="axis"></param>
  870. /// <returns></returns>
  871. public int GetMMtoPlus(AxisName axis)
  872. {
  873. switch (axis)
  874. {
  875. case AxisName.Axis0:
  876. return HomeParamsX1.MM2PulseNum;
  877. case AxisName.Axis1:
  878. return HomeParamsX2.MM2PulseNum;
  879. case AxisName.Axis2:
  880. return HomeParamsY.MM2PulseNum;
  881. case AxisName.Axis3:
  882. return HomeParamsZ.MM2PulseNum;
  883. default: return 1;
  884. }
  885. }
  886. /// <summary>
  887. /// I/O指令输出
  888. /// </summary>
  889. /// <param name="processParam"></param>
  890. /// <param name="isStrobe">频闪</param>
  891. /// <param name="recover">输出sleep(recoverWaitTime)下,后恢复原信号</param>
  892. /// <param name="recoverWaitTime">sleep 后反转</param>
  893. public bool io_output(string tagName, JObject processParam, bool isStrobe = false, bool recover = false, int recoverWaitTime = 100)
  894. {
  895. bool result = false;
  896. string[] OUT_OP_SHOW = processParam.Value<JArray>("OUT_OP_SHOW").ToObject<List<string>>().ToArray();
  897. OUT_OP_SHOW = IODataFormatBinaryStr(OUT_OP_SHOW, true);
  898. for (int i = 0; i < OUT_OP_SHOW.Length; i++)
  899. {
  900. for (int j = 0; j < OUT_OP_SHOW[i].Length; j++)
  901. {
  902. int jj = OUT_OP_SHOW[i].Length - j - 1;
  903. if (OUT_OP_SHOW[i][jj] == 'L' || OUT_OP_SHOW[i][jj] == 'H')
  904. {
  905. if (recover)
  906. {
  907. if (recoverWaitTime > 0)
  908. {
  909. ioCardDev.WriteBitState(i, j, OUT_OP_SHOW[i][jj] == 'H');
  910. Thread.Sleep(recoverWaitTime);
  911. }
  912. ioCardDev.WriteBitState(i, j, OUT_OP_SHOW[i][jj] == 'L');
  913. }
  914. else
  915. {
  916. ioCardDev.WriteBitState(i, j, OUT_OP_SHOW[i][jj] == 'H');
  917. }
  918. result = true;
  919. }
  920. }
  921. }
  922. return result;
  923. }
  924. /// <summary>
  925. /// 多轴判断到位
  926. /// </summary>
  927. /// <param name="axisList"></param>
  928. /// <returns></returns>
  929. public bool WaitAxisDone(List<int> axisList)
  930. {
  931. foreach (int i in axisList)
  932. {
  933. if (axisDev.CheckDone(i, 30) != 0)
  934. {
  935. return false;
  936. }
  937. }
  938. return true;
  939. }
  940. public bool WaitAllAxisDone()
  941. {
  942. for (int i = 0; i < 4; i++)
  943. {
  944. if (axisDev.CheckDone(i, 30) != 0)
  945. {
  946. return false;
  947. }
  948. }
  949. return true;
  950. }
  951. public double GetAxisPosValueMM(int axisNo)
  952. {
  953. double pos = axisDev.GetFeedbackPos(axisNo);
  954. return pos / (double)GetMMtoPlus((AxisName)axisNo);
  955. }
  956. #endregion
  957. #endregion
  958. #region 公开字段
  959. private bool _isInit;
  960. /// <summary>
  961. /// 是否初始化完成
  962. /// </summary>
  963. public bool IsInit { get { return _isInit; } }
  964. private bool _isRuning;
  965. /// <summary>
  966. /// 设备正在运行
  967. /// </summary>
  968. public bool IsRuning { get { return _isRuning; } }
  969. private bool _isAuto;
  970. /// <summary>
  971. /// 设备正在自动化流程中
  972. /// </summary>
  973. public bool IsAuto { get { return _isAuto; } }
  974. #endregion
  975. #region 用户+登入+管理
  976. /// <summary>
  977. /// 登入
  978. /// </summary>
  979. /// <returns></returns>
  980. public bool LoginSystem()
  981. {
  982. return userMgr.UserLoginDialog();
  983. }
  984. /// <summary>
  985. /// 用户权限
  986. /// </summary>
  987. public void UserPermissiomMgr()
  988. {
  989. userMgr.RightManageDialog();
  990. }
  991. /// <summary>
  992. /// 用户管理
  993. /// </summary>
  994. public void UserListMgr()
  995. {
  996. userMgr.UserManagerDialog();
  997. }
  998. #endregion
  999. #region 系统初始化&&运行
  1000. /// <summary>
  1001. /// 系统初始化
  1002. /// </summary>
  1003. /// <returns></returns>
  1004. public bool Initial()
  1005. {
  1006. try
  1007. {
  1008. bool ret = false;
  1009. string err = "";
  1010. InitLog("系统开始初始化...");
  1011. //Thread.Sleep(200);
  1012. // 加载系统配置
  1013. InitLog("加载系统参数...");
  1014. ret = confMgr.LoadSystemConfig();
  1015. if (!ret)
  1016. {
  1017. throw new Exception("系统参数加载失败...");
  1018. }
  1019. InitLog("系统参数加载完成!");
  1020. //根据llog路径,开始记录日志
  1021. statusMgr.StartLog(confMgr.SysConfigParams.LogPath);
  1022. statusMgr.GotoInitial();
  1023. SendStatus();
  1024. //Thread.Sleep(200);
  1025. // 硬件初始化
  1026. if (!InitAllDev())
  1027. {
  1028. throw new Exception("硬件初始化失败...");
  1029. }
  1030. InitLog("硬件初始化完成!");
  1031. // 加载硬件配置
  1032. InitLog("加载硬件驱动参数...");
  1033. if (!LoadDevConfig())
  1034. {
  1035. throw new Exception("加载硬件驱动参数失败...");
  1036. }
  1037. InitLog("加载硬件驱动参数完成!");
  1038. //Thread.Sleep(200);
  1039. // 处理运行
  1040. InitLog("AI算法核心初始化...");
  1041. if (!defectLib.start())
  1042. throw new Exception("外观检测核心初始化失败...");
  1043. if (!sizeLib.start(confMgr.SysConfigParams.ImageProcessPath))
  1044. throw new Exception("尺寸检测核心初始化失败...");
  1045. InitLog("AI算法核心初始化完成!");
  1046. InitLog("镜头电机回原...");
  1047. //镜头电机回原
  1048. lensMotorDev.BackHome(0, new HomeVelocityParams());
  1049. lensMotorDev.CheckHomeDone(0, 3000);
  1050. //移动到 4.5X
  1051. //lensMotorDev.MoveAbsPulse(0, new VelocityCurveParams(), (int)SmallAxCmdPos.倍率4_5X);
  1052. //lensMotorDev.CheckDone(0, 5000);
  1053. InitLog("镜头电机回原完成!");
  1054. //移动Axis前等待厚度传感器收回
  1055. InitLog("检测厚度传感器安全值...");
  1056. double TempVal = thicknessDev.GetValue();
  1057. if (TempVal < Math.Abs(confMgr.SysConfigParams.ThicknessSafeValue))
  1058. throw new Exception("厚度传感器不在安全位置!");
  1059. //多轴回原
  1060. if (confMgr.SysConfigParams.OpenAutoGoHome)
  1061. {
  1062. if ((homeParamsZ != null) && (homeParamsX1 != null) && (homeParamsX2 != null) && (homeParamsY != null))
  1063. {
  1064. axisDev.ResetAxisState((int)AxisName.Axis0);
  1065. axisDev.ResetAxisState((int)AxisName.Axis1);
  1066. axisDev.ResetAxisState((int)AxisName.Axis2);
  1067. axisDev.ResetAxisState((int)AxisName.Axis3);
  1068. InitLog("Z轴开始回原点...");
  1069. axisDev.BackHome((int)AxisName.Axis3, homeParamsZ);
  1070. InitLog("X1轴开始回原点...");
  1071. axisDev.BackHome((int)AxisName.Axis0, homeParamsX1);
  1072. InitLog("X2轴开始回原点...");
  1073. axisDev.BackHome((int)AxisName.Axis1, homeParamsX2);
  1074. InitLog("Y轴开始回原点...");
  1075. //axisDev.BackHome((int)AxisName.Axis1, homeParamsY);
  1076. //y轴使用io回原
  1077. if (!AxisYGoHome())
  1078. throw new Exception("Y轴回原报警!");
  1079. }
  1080. Thread.Sleep(1000);
  1081. //判断轴是否回原成功
  1082. if (!AxisYGoHomeDone(60))
  1083. {
  1084. AxisAllImmediateStop();
  1085. throw new Exception("Y轴回原失败!");
  1086. }
  1087. if (axisDev.CheckHomeDone((int)AxisName.Axis0, 60) != 0)
  1088. {
  1089. AxisAllImmediateStop();
  1090. throw new Exception("X1轴回原失败!");
  1091. }
  1092. if (axisDev.CheckHomeDone((int)AxisName.Axis1, 60) != 0)
  1093. {
  1094. AxisAllImmediateStop();
  1095. throw new Exception("X2轴回原失败!");
  1096. }
  1097. if (axisDev.CheckHomeDone((int)AxisName.Axis3, 60) != 0)
  1098. {
  1099. AxisAllImmediateStop();
  1100. throw new Exception("Z轴回原失败!");
  1101. }
  1102. InitLog("所有轴回原成功!");
  1103. //清空y轴发送命令和反馈位置
  1104. axisDev.SetCommandPos((int)AxisName.Axis2, 0);
  1105. axisDev.SetFeedbackPos((int)AxisName.Axis2, 0);
  1106. //X轴标定启用
  1107. if(confMgr.SysConfigParams.OpenAxisXCalibration)
  1108. {
  1109. OpenAxisXCal();
  1110. }
  1111. }
  1112. LedReady();
  1113. if (confMgr.SysConfigParams.OpenAutoGoHome)
  1114. {
  1115. InitLog("移动到上料...");
  1116. //Thread.Sleep(500);
  1117. if (!GotoLoadPos())
  1118. {
  1119. throw new Exception("移动到上料失败!");
  1120. }
  1121. }
  1122. //初始化成功
  1123. _isInit = true;
  1124. statusMgr.GotoNormalStandby();
  1125. SendStatus();
  1126. OnInitRuning(new InitEventArgs("系统初始化完成...", this.IsInit));
  1127. Run();
  1128. return ret;
  1129. }
  1130. catch (Exception ex)
  1131. {
  1132. InitLog(ex.Message, "初始化", WarningEnum.High);
  1133. InitLog("系统初始化失败!" , "初始化", WarningEnum.High);
  1134. //statusMgr.GotoWarning(MaiMuControl.Device.WarningEnum.High, "初始化", ex.Message);
  1135. return false;
  1136. }
  1137. }
  1138. /// <summary>
  1139. /// 初始化图像处理报警
  1140. /// </summary>
  1141. /// <returns></returns>
  1142. public bool InitDefectEvent()
  1143. {
  1144. defectLib.WarningEvent = (warning, msg) =>
  1145. {
  1146. Log("缺陷处理", msg, warning);
  1147. };
  1148. sizeLib.WarningEvent = (warning, msg) =>
  1149. {
  1150. Log("尺寸检测", msg, warning);
  1151. };
  1152. return true;
  1153. }
  1154. /// <summary>
  1155. /// 开启修复台web服务器
  1156. /// </summary>
  1157. /// <returns></returns>
  1158. public bool InitWebServer()
  1159. {
  1160. //InitLog("开启数据服务器...");
  1161. webService.Defect_Compress_SavePath = confMgr.SysConfigParams.DefectRepairImag.SavePath;
  1162. webService.SizeBmp_Zoom_Image_SavePath = confMgr.SysConfigParams.SizeRepairImag.SavePath;
  1163. webService.LogEvent = (warning, msg) =>
  1164. {
  1165. Log("HTTP服务", msg, warning);
  1166. //OnMainRuning(new MainEventArgs("HTTP服务", msg, warning));
  1167. if(!confMgr.SysConfigParams.OpenHttpLog)
  1168. webService.LogEvent = null;
  1169. };
  1170. webService.start(confMgr.SysConfigParams.HttpServerIP, confMgr.SysConfigParams.HttpServerPort);
  1171. //InitLog("开启数据服务器完成!");
  1172. Thread.Sleep(200);
  1173. return true;
  1174. }
  1175. public bool InitCloudConnect()
  1176. {
  1177. if (confMgr.SysConfigParams.OpenCloud)
  1178. {
  1179. if (cloudMgr.ConnectCloud(confMgr.SysConfigParams.CloudServerIP, confMgr.SysConfigParams.CloudServerPort,
  1180. confMgr.SysConfigParams.CloudUser, confMgr.SysConfigParams.CloudPassword))
  1181. {
  1182. init_Cloud = true;
  1183. Log("云端数据", "开启云端连接");
  1184. return true;
  1185. }
  1186. Log("云端数据", "云端连接失败!", WarningEnum.Low);
  1187. return false;
  1188. }
  1189. return true;
  1190. }
  1191. /// <summary>
  1192. /// 运行主线程
  1193. /// </summary>
  1194. private void Run()
  1195. {
  1196. _mainThread = new Thread(() =>
  1197. {
  1198. MainThreadFunction();
  1199. });
  1200. _mainThread.IsBackground = true;
  1201. _mainThread.Start();
  1202. }
  1203. #endregion
  1204. #region 系统关闭
  1205. /// <summary>
  1206. /// 关闭
  1207. /// </summary>
  1208. public void Close()
  1209. {
  1210. _isInit = false;
  1211. _isRuning = false;
  1212. if (null != _cts)
  1213. {
  1214. _cts.Cancel();
  1215. }
  1216. if (null != _mainThread)
  1217. {
  1218. _mainThread.Join(1000);
  1219. }
  1220. webService.stop();
  1221. AxisDStop();
  1222. axisDev.SetServo((int)AxisName.Axis0, 0);
  1223. axisDev.SetServo((int)AxisName.Axis1, 0);
  1224. axisDev.SetServo((int)AxisName.Axis2, 0);
  1225. axisDev.SetServo((int)AxisName.Axis3, 0);
  1226. axisDev.CloseBoard();
  1227. //关闭相机
  1228. camDevFront.CloseCamera();
  1229. camDevBack.CloseCamera();
  1230. //关闭光源
  1231. for (int i = 0; i < LightChCount; i++)
  1232. {
  1233. lightDev.CloseLight(i + 1);
  1234. }
  1235. //lightDev.CloseLight((int)LightChannelEnum.CH1);
  1236. //lightDev.CloseLight((int)LightChannelEnum.CH2);
  1237. //lightDev.CloseLight((int)LightChannelEnum.CH3);
  1238. //lightDev.CloseLight((int)LightChannelEnum.CH4);
  1239. //lightDev.CloseLight((int)LightChannelEnum.CH5);
  1240. //lightDev.CloseLight((int)LightChannelEnum.CH6);
  1241. lightDev.CloseDev();
  1242. //关闭传感器
  1243. thicknessDev.CloseDev();
  1244. tensionDev.CloseDev();
  1245. lensMotorDev.CloseBoard();
  1246. //关闭io
  1247. ioCardDev.ResetAllDO();
  1248. ioCardDev.CloseBoard();
  1249. }
  1250. #endregion
  1251. #region 产品管理
  1252. public string SelectProduct()
  1253. {
  1254. InputFrm frm = new InputFrm(productCodeList, "请选择产品料号:");
  1255. if (frm.ShowDialog() != DialogResult.OK && string.IsNullOrWhiteSpace(frm.inputData))
  1256. return "";
  1257. //显示料号
  1258. //this.txtProductCode.Text = frm.inputData;
  1259. var model = PdtService.GetModelNav(frm.inputData);
  1260. if (model != null && model.StepInfo.ProcessList.Count > 0)
  1261. {
  1262. //名称料号显示一个就可以
  1263. return model.Code;
  1264. }
  1265. return "";
  1266. }
  1267. /// <summary>
  1268. /// 拷贝产品
  1269. /// </summary>
  1270. /// <param name="list"></param>
  1271. /// <param name="liIndex"></param>
  1272. /// <returns></returns>
  1273. public bool ProductCopy(List<Product> list, int liIndex)
  1274. {
  1275. Product newProduct = new Product()
  1276. {
  1277. Code = list[liIndex].Code + "_clone",
  1278. Name = $"{list[liIndex].Name} (克隆)",
  1279. Spec = list[liIndex].Spec,
  1280. ClassesId = list[liIndex].ClassesId,
  1281. ClassesInfo = list[liIndex].ClassesInfo,
  1282. HoleCount = list[liIndex].HoleCount,
  1283. DefectModelFile = list[liIndex].DefectModelFile,
  1284. AttachmentList = new List<Attachment>(),
  1285. BatchId = list[liIndex].BatchId,
  1286. TargetCount = list[liIndex].TargetCount,
  1287. CompleteCount = list[liIndex].CompleteCount,
  1288. BatchHistoryList = new List<BatchHistory>(),
  1289. QualifiedCriterionList = new List<QualifiedCriterion>(),
  1290. Note = list[liIndex].Note,
  1291. TensionBaseValue = list[liIndex].TensionBaseValue,
  1292. TensionUpFloatValue = list[liIndex].TensionUpFloatValue,
  1293. TensionDownFloatValue = list[liIndex].TensionDownFloatValue,
  1294. HeightBaseValue = list[liIndex].HeightBaseValue,
  1295. HeightUpFloatValue = list[liIndex].HeightUpFloatValue,
  1296. HeightDownFloatValue = list[liIndex].HeightDownFloatValue,
  1297. LineWidthBaseValue = list[liIndex].LineWidthBaseValue,
  1298. LineWidthUpFloatValue = list[liIndex].LineWidthUpFloatValue,
  1299. LineWidthDownFloatValue = list[liIndex].LineWidthDownFloatValue,
  1300. PTBaseValue = list[liIndex].PTBaseValue,
  1301. PTUpFloatValue = list[liIndex].PTUpFloatValue,
  1302. PTDownFloatValue = list[liIndex].PTDownFloatValue,
  1303. HeightBaseDec = list[liIndex].HeightBaseDec,
  1304. StepId = list[liIndex].StepId,
  1305. StepInfo = list[liIndex].StepInfo,
  1306. ProductProcessList = new List<ProductProcess>(),
  1307. ReviseStepId = list[liIndex].ReviseStepId,
  1308. ReviseStepInfo = list[liIndex].ReviseStepInfo,
  1309. ProductReviseProcessList = new List<ProductReviseProcess>(),
  1310. AssistStepId = list[liIndex].AssistStepId,
  1311. AssistStepInfo = list[liIndex].AssistStepInfo,
  1312. ProductAssistProcessList = new List<ProductAssistProcess>(),
  1313. //OrderList = new List<Order>(),
  1314. ModifyUserCode = userMgr.LoginUser.Code,
  1315. CreateUserCode = userMgr.LoginUser.Code
  1316. };
  1317. foreach (var item in list[liIndex].AttachmentList)
  1318. {
  1319. newProduct.AttachmentList.Add(new Attachment()
  1320. {
  1321. TBName = item.TBName,
  1322. Type = item.Type,
  1323. Pid = item.Pid,
  1324. Name = item.Name,
  1325. NameTimestamp = item.NameTimestamp,
  1326. ExtendName = item.ExtendName,
  1327. ModifyUserCode = userMgr.LoginUser.Code,
  1328. CreateUserCode = userMgr.LoginUser.Code
  1329. });
  1330. }
  1331. foreach (var item in list[liIndex].BatchHistoryList)
  1332. {
  1333. newProduct.BatchHistoryList.Add(new BatchHistory()
  1334. {
  1335. Pid = item.Pid,
  1336. BatchId = item.BatchId,
  1337. TargetCount = item.TargetCount,
  1338. CompleteCount = item.CompleteCount,
  1339. ModifyUserCode = userMgr.LoginUser.Code,
  1340. CreateUserCode = userMgr.LoginUser.Code
  1341. });
  1342. }
  1343. foreach (var item in list[liIndex].QualifiedCriterionList)
  1344. {
  1345. newProduct.QualifiedCriterionList.Add(new QualifiedCriterion()
  1346. {
  1347. Pid = item.Pid,
  1348. DefectCode = item.DefectCode,
  1349. Size = item.Size,
  1350. MaxDefectCount = item.MaxDefectCount,
  1351. ModifyUserCode = userMgr.LoginUser.Code,
  1352. CreateUserCode = userMgr.LoginUser.Code
  1353. });
  1354. }
  1355. foreach (var item in list[liIndex].ProductProcessList)
  1356. {
  1357. newProduct.ProductProcessList.Add(new ProductProcess()
  1358. {
  1359. Pid = item.Pid,
  1360. ProcessCode = item.ProcessCode,
  1361. ProcessParams = item.ProcessParams,
  1362. ModifyUserCode = userMgr.LoginUser.Code,
  1363. CreateUserCode = userMgr.LoginUser.Code
  1364. });
  1365. }
  1366. foreach (var item in list[liIndex].ProductReviseProcessList)
  1367. {
  1368. newProduct.ProductReviseProcessList.Add(new ProductReviseProcess()
  1369. {
  1370. Pid = item.Pid,
  1371. ProcessCode = item.ProcessCode,
  1372. ProcessParams = item.ProcessParams,
  1373. ModifyUserCode = userMgr.LoginUser.Code,
  1374. CreateUserCode = userMgr.LoginUser.Code
  1375. });
  1376. }
  1377. foreach (var item in list[liIndex].ProductAssistProcessList)
  1378. {
  1379. newProduct.ProductAssistProcessList.Add(new ProductAssistProcess()
  1380. {
  1381. Pid = item.Pid,
  1382. ProcessCode = item.ProcessCode,
  1383. ProcessParams = item.ProcessParams,
  1384. ModifyUserCode = userMgr.LoginUser.Code,
  1385. CreateUserCode = userMgr.LoginUser.Code
  1386. });
  1387. }
  1388. /*
  1389. foreach (var item in list[liIndex].OrderList)
  1390. {
  1391. newProduct.OrderList.Add(new Order()
  1392. {
  1393. ProductId = item.ProductId,
  1394. ProductInfo = item.ProductInfo,
  1395. SN = item.SN,
  1396. ModifyUserCode = Config.loginUser.Code,
  1397. CreateUserCode = Config.loginUser.Code
  1398. });
  1399. }*/
  1400. bool result = PdtService.InsertNav(newProduct);
  1401. return result;
  1402. }
  1403. /// <summary>
  1404. /// 加载产品列表
  1405. /// </summary>
  1406. public void LoadProductCodeList()
  1407. {
  1408. try
  1409. {
  1410. productCodeList = PdtService.GetList().Select(m => m.Code).ToList();
  1411. productIdList = PdtService.GetList().Select(m => m.Id).ToList();
  1412. //string[] array = ReadSNText();
  1413. //if (array != null && array.Length > 0)
  1414. //{
  1415. // for (int i = 0; i < array.Length; i++)
  1416. // productSNList.Add(array[i]);
  1417. //}
  1418. }
  1419. catch (Exception ex)
  1420. {
  1421. //throw new Exception("加载产品料号失败:" + ex.Message);
  1422. OnMainRuning(new MainEventArgs("启动", "加载产品料号失败:" + ex.Message, WarningEnum.High));
  1423. statusMgr.GotoWarning(WarningEnum.High, "启动", "加载产品料号失败:" + ex.Message);
  1424. SendStatus();
  1425. }
  1426. }
  1427. /// <summary>
  1428. /// 记录使用的sn
  1429. /// </summary>
  1430. /// <param name="str"></param>
  1431. public void Remind(string str)
  1432. {
  1433. string workPath = Directory.GetCurrentDirectory();
  1434. string textPath = Path.Combine(workPath, "TextRemind.txt");
  1435. try
  1436. {
  1437. if (productSNList.Count == 0 || !productSNList.Contains(str))
  1438. {
  1439. if (productSNList.Count > 20)
  1440. productSNList.RemoveAt(0);
  1441. productSNList.Add(str);
  1442. //File.AppendAllLines(textPath, new string[] { str });
  1443. }
  1444. if(productSNList.Count > 0)
  1445. {
  1446. File.WriteAllLines(textPath, productSNList);
  1447. }
  1448. }
  1449. catch
  1450. {
  1451. }
  1452. }
  1453. /// <summary>
  1454. /// 读取近期sn
  1455. /// </summary>
  1456. /// <returns></returns>
  1457. private string[] ReadSNText()
  1458. {
  1459. string workPath = Directory.GetCurrentDirectory();
  1460. string textPath = Path.Combine(workPath, "TextRemind.txt");
  1461. try
  1462. {
  1463. if (!File.Exists(textPath))
  1464. return null;
  1465. return File.ReadAllLines(textPath);
  1466. }
  1467. catch
  1468. {
  1469. return null;
  1470. }
  1471. }
  1472. #endregion
  1473. #region 流程步骤
  1474. private static void InitDevDic()
  1475. {
  1476. //旧版流程
  1477. //dicDevType.Add("CodeScanner", "扫码枪");//固定为必有开始
  1478. if (!dicDevType.ContainsKey("IOCard")) dicDevType.Add("IOCard", "I/O控制");
  1479. //if (!dicDevType.ContainsKey("Tension")) dicDevType.Add("Tension", "张力测量");
  1480. if (!dicDevType.ContainsKey("Height")) dicDevType.Add("Height", "厚度测量");
  1481. if (!dicDevType.ContainsKey("Axis")) dicDevType.Add("Axis", "滑台电机");
  1482. if (!dicDevType.ContainsKey("AxisTag")) dicDevType.Add("AxisTag", "滑台&测量");
  1483. if (!dicDevType.ContainsKey("Light")) dicDevType.Add("Light", "光源");
  1484. if (!dicDevType.ContainsKey("Scanner_CC")) dicDevType.Add("Scanner_CC", "前部相机拍照");
  1485. if (!dicDevType.ContainsKey("Scanner_GENTL")) dicDevType.Add("Scanner_GENTL", "后部相机拍照");
  1486. if (!dicDevType.ContainsKey("SmallAxis")) dicDevType.Add("SmallAxis", "镜头电机");
  1487. if (!dicDevType.ContainsKey("Defect")) dicDevType.Add("Defect", "缺陷检测");
  1488. if (!dicDevType.ContainsKey("Size")) dicDevType.Add("Size", "尺寸测量");
  1489. if (!dicDevType.ContainsKey("For")) dicDevType.Add("For", "For循环");
  1490. if (!dicDevType.ContainsKey("If")) dicDevType.Add("If", "If条件");
  1491. //新版流程
  1492. if (!ProcessType.ContainsKey("Tension")) ProcessType.Add("Tension", "张力测量");
  1493. if (!ProcessType.ContainsKey("Height")) ProcessType.Add("Height", "厚度测量");
  1494. if (!ProcessType.ContainsKey("LensMotor")) ProcessType.Add("LensMotor", "镜头变焦");
  1495. if (!ProcessType.ContainsKey("Light")) ProcessType.Add("Light", "光源设置");
  1496. if (!ProcessType.ContainsKey("Mark")) ProcessType.Add("Mark", "Mark检测");
  1497. if (!ProcessType.ContainsKey("PointTest")) ProcessType.Add("PointTest", "尺寸检测");
  1498. if (!ProcessType.ContainsKey("SizeAndDefect")) ProcessType.Add("SizeAndDefect", "外观检测");
  1499. if (!ProcessType.ContainsKey("For")) ProcessType.Add("For", "测试循环");
  1500. }
  1501. #endregion
  1502. #region 操作
  1503. #region webLogg
  1504. public void CheckWebLog()
  1505. {
  1506. if (!confMgr.SysConfigParams.OpenHttpLog)
  1507. webService.LogEvent = null;
  1508. else
  1509. {
  1510. webService.LogEvent = (warning, msg) =>
  1511. {
  1512. Log("HTTP服务", msg, warning);
  1513. //OnMainRuning(new MainEventArgs("HTTP服务", msg, warning));
  1514. };
  1515. }
  1516. }
  1517. #endregion
  1518. #region 上料移动
  1519. /// <summary>
  1520. /// 关闭光源移动到上料位置
  1521. /// </summary>
  1522. /// <returns></returns>
  1523. public bool GotoLoadPos()
  1524. {
  1525. bool ret = true;
  1526. //关闭光源
  1527. for (int i = 0; i < LightChCount; i++)
  1528. {
  1529. lightDev.CloseLight(i + 1);
  1530. }
  1531. VelocityCurveParams vel_z = new VelocityCurveParams(DefaultSpeed / 2, DefaultSpeed / 2, 0, DefaultSpeed / 2, 1, GetMMtoPlus(AxisName.Axis3));
  1532. axisDev.MoveAbsValue((int)AxisName.Axis3, vel_z, confMgr.LoadPoint_Z);
  1533. if (axisDev.CheckDone((int)AxisName.Axis3, 30) != 0)
  1534. return false;
  1535. VelocityCurveParams vel_x1 = new VelocityCurveParams(DefaultSpeed, DefaultSpeed, 0, DefaultSpeed, 1, GetMMtoPlus(AxisName.Axis0));
  1536. axisDev.MoveAbsValue((int)AxisName.Axis0, vel_x1, confMgr.LoadPoint_X1);
  1537. VelocityCurveParams vel_x2 = new VelocityCurveParams(DefaultSpeed, DefaultSpeed, 0, DefaultSpeed, 1, GetMMtoPlus(AxisName.Axis1));
  1538. axisDev.MoveAbsValue((int)AxisName.Axis1, vel_x2, confMgr.LoadPoint_X2);
  1539. VelocityCurveParams vel_y = new VelocityCurveParams(DefaultSpeed, DefaultSpeed, 0, DefaultSpeed, 1, GetMMtoPlus(AxisName.Axis2));
  1540. axisDev.MoveAbsValue((int)AxisName.Axis2, vel_y, confMgr.LoadPoint_Y);
  1541. if (axisDev.CheckDone((int)AxisName.Axis0, 30) != 0)
  1542. return false;
  1543. if (axisDev.CheckDone((int)AxisName.Axis1, 30) != 0)
  1544. return false;
  1545. if (axisDev.CheckDone((int)AxisName.Axis2, 30) != 0)
  1546. return false;
  1547. return ret;
  1548. }
  1549. #endregion
  1550. #region 急停
  1551. /// <summary>
  1552. /// 急停设备
  1553. /// </summary>
  1554. public void EmergencyStop()
  1555. {
  1556. Log("设备", "紧急停止", WarningEnum.High);
  1557. _isAuto = false;
  1558. AxisAllImmediateStop();
  1559. }
  1560. #endregion
  1561. #region IO气缸
  1562. private int GetIOPortIndex(int DIDOEnum)
  1563. {
  1564. return DIDOEnum / 8;
  1565. }
  1566. private int GetIOBitIndex(int DIDOEnum)
  1567. {
  1568. return DIDOEnum % 8;
  1569. }
  1570. /// <summary>
  1571. /// 开关照明灯
  1572. /// </summary>
  1573. /// <param name="open"></param>
  1574. public void OpenFloodlight(bool open)
  1575. {
  1576. ////记录日产量
  1577. //if (confMgr.SetDailyOutputAdd(out DailyOutput))
  1578. //{
  1579. // SendDailyOutput();
  1580. //}
  1581. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.日光灯), GetIOBitIndex((int)DOName.日光灯), open);
  1582. }
  1583. /// <summary>
  1584. /// 产品夹紧气缸控制
  1585. /// </summary>
  1586. /// <param name="ack"></param>
  1587. /// <returns></returns>
  1588. public bool RunQG(bool ack)
  1589. {
  1590. bool ret;
  1591. ret = ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.加紧气缸), GetIOBitIndex((int)DOName.加紧气缸), ack);
  1592. Thread.Sleep(500);
  1593. //ret = ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.加紧气缸), GetIOBitIndex((int)DOName.加紧气缸), ack);
  1594. return ret;
  1595. }
  1596. /// <summary>
  1597. /// 获取加紧气缸IO状态
  1598. /// </summary>
  1599. /// <returns></returns>
  1600. public bool QGSts()
  1601. {
  1602. bool sts;
  1603. ioCardDev.GetDOBitState(GetIOPortIndex((int)DOName.加紧气缸), GetIOBitIndex((int)DOName.加紧气缸), out sts);
  1604. return sts;
  1605. }
  1606. /// <summary>
  1607. /// 测厚气缸控制
  1608. /// </summary>
  1609. /// <param name="ack"></param>
  1610. /// <returns></returns>
  1611. public bool RunThickness(bool ack)
  1612. {
  1613. bool ret;
  1614. ret = ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), ack);
  1615. Thread.Sleep(500);
  1616. return ret;
  1617. }
  1618. /// <summary>
  1619. /// 获取测厚气缸IO状态
  1620. /// </summary>
  1621. /// <returns></returns>
  1622. public bool ThicknessSts()
  1623. {
  1624. bool sts;
  1625. ioCardDev.GetDOBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), out sts);
  1626. return sts;
  1627. }
  1628. #endregion
  1629. #region 测厚安全
  1630. /// <summary>
  1631. /// 判断测厚气缸是否在安全位置
  1632. /// </summary>
  1633. /// <returns></returns>
  1634. public bool ThicknessIsSafe()
  1635. {
  1636. //RunThickness(false);
  1637. bool sts;
  1638. ioCardDev.GetDOBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), out sts);
  1639. if(sts)
  1640. return false;
  1641. if (thicknessDev.GetValue() < Math.Abs(confMgr.SysConfigParams.ThicknessSafeValue))
  1642. return false;
  1643. return true;
  1644. }
  1645. #endregion
  1646. #region 三色灯
  1647. /// <summary>
  1648. /// 三色灯初始化
  1649. /// </summary>
  1650. public void LedReady()
  1651. {
  1652. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  1653. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), false);
  1654. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), false);
  1655. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  1656. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  1657. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.复位按钮黄灯), GetIOBitIndex((int)DOName.复位按钮黄灯), false);
  1658. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), false);
  1659. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  1660. }
  1661. /// <summary>
  1662. /// 运行状态三色灯
  1663. /// </summary>
  1664. public void LedRun()
  1665. {
  1666. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), true);
  1667. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), false);
  1668. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), false);
  1669. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  1670. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), true);
  1671. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.复位按钮黄灯), GetIOBitIndex((int)DOName.复位按钮黄灯), false);
  1672. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), false);
  1673. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  1674. }
  1675. /// <summary>
  1676. /// 暂停状态三色灯
  1677. /// </summary>
  1678. public void LedPause()
  1679. {
  1680. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  1681. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), false);
  1682. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), true);
  1683. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  1684. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  1685. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.复位按钮黄灯), GetIOBitIndex((int)DOName.复位按钮黄灯), false);
  1686. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), true);
  1687. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  1688. }
  1689. //控制黄灯闪烁
  1690. private bool Blink;
  1691. private int BlinkCnt = 0;
  1692. //控制蜂鸣间隔
  1693. private int BuzzCnt = 0;
  1694. /// <summary>
  1695. /// 回原状态三色灯
  1696. /// </summary>
  1697. /// <param name="val"></param>
  1698. public void LedRset(bool val)
  1699. {
  1700. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  1701. //ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), val);
  1702. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), false);
  1703. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  1704. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  1705. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.复位按钮黄灯), GetIOBitIndex((int)DOName.复位按钮黄灯), val);
  1706. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), false);
  1707. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  1708. Blink = val;
  1709. BlinkCnt = 0;
  1710. }
  1711. #endregion
  1712. #region 轴回原
  1713. /// <summary>
  1714. /// 启用X轴标定
  1715. /// </summary>
  1716. private void OpenAxisXCal()
  1717. {
  1718. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.X1回原), GetIOBitIndex((int)DOName.X1回原), true);
  1719. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.X2回原), GetIOBitIndex((int)DOName.X2回原), true);
  1720. Thread.Sleep(300);
  1721. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.X1回原), GetIOBitIndex((int)DOName.X1回原), false);
  1722. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.X2回原), GetIOBitIndex((int)DOName.X2回原), false);
  1723. }
  1724. /// <summary>
  1725. /// Y轴回原,使用信号回原,因为驱动器中有标定参数需要驱动器控制回原才起效
  1726. /// </summary>
  1727. /// <returns></returns>
  1728. private bool AxisYGoHome()
  1729. {
  1730. //加入读取急停信号
  1731. AxisSignalState axisSignalState = axisDev.GetAxisState((int)AxisName.Axis2);
  1732. if(axisSignalState.EMG != GeneralElectricalLevelMode.High)
  1733. {
  1734. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.Y轴回原点), GetIOBitIndex((int)DOName.Y轴回原点), true);
  1735. return true;
  1736. }
  1737. return false;
  1738. }
  1739. /// <summary>
  1740. /// 判断y轴是否回原
  1741. /// </summary>
  1742. /// <param name="timeout"></param>
  1743. /// <returns></returns>
  1744. private bool AxisYGoHomeDone(double timeout)
  1745. {
  1746. System.Diagnostics.Stopwatch strtime = new System.Diagnostics.Stopwatch();
  1747. strtime.Start();
  1748. do
  1749. {
  1750. //加入读取急停信号
  1751. AxisSignalState axisSignalState = axisDev.GetAxisState((int)AxisName.Axis2);
  1752. if (axisSignalState.EMG == GeneralElectricalLevelMode.High)
  1753. {
  1754. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.Y轴回原点), GetIOBitIndex((int)DOName.Y轴回原点), false);
  1755. return false;
  1756. }
  1757. //判断是否正常停止
  1758. bool sts;
  1759. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.Y轴回原点完成), GetIOBitIndex((int)DIName.Y轴回原点完成), out sts);
  1760. if (sts)
  1761. break;
  1762. //检查是否超时
  1763. strtime.Stop();
  1764. if (strtime.ElapsedMilliseconds / 1000.0 > timeout)
  1765. {
  1766. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.Y轴回原点), GetIOBitIndex((int)DOName.Y轴回原点), false);
  1767. return false;
  1768. }
  1769. strtime.Start();
  1770. //延时
  1771. System.Threading.Thread.Sleep(20);
  1772. } while (true);
  1773. Thread.Sleep(500);
  1774. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.Y轴回原点), GetIOBitIndex((int)DOName.Y轴回原点), false);
  1775. return true;
  1776. }
  1777. #endregion
  1778. #region 上料位
  1779. public bool GotoReadyPosAndIO()
  1780. {
  1781. Log("复位", "系统复位");
  1782. _isAuto = false;
  1783. CurrProcessIndex = -1;
  1784. CurrPoinntCount = 0;
  1785. CurrStepResult = 0;
  1786. if(!RunThickness(false))
  1787. {
  1788. Log("复位", "测厚气缸复位失败", WarningEnum.High);
  1789. return false;
  1790. }
  1791. bool ret = GotoLoadPos();
  1792. if (!ret)
  1793. {
  1794. Log("复位", "系统电机复位失败", WarningEnum.High);
  1795. return false;
  1796. }
  1797. if (!RunQG(false))
  1798. {
  1799. Log("复位", "加紧气缸复位失败", WarningEnum.High);
  1800. return false;
  1801. }
  1802. LedReady();
  1803. statusMgr.GotoNormalStandby();
  1804. SendStatus();
  1805. Log("复位", "复位完成");
  1806. return ret;
  1807. }
  1808. /// <summary>
  1809. /// 确认当前位置为上料位置
  1810. /// </summary>
  1811. /// <returns></returns>
  1812. private bool CheckPosIsLoadPos()
  1813. {
  1814. bool ret = false;
  1815. double x1 = GetAxisPosValueMM((int)AxisName.Axis0);
  1816. double x2 = GetAxisPosValueMM((int)AxisName.Axis1);
  1817. double y = GetAxisPosValueMM((int)AxisName.Axis2);
  1818. double z = GetAxisPosValueMM((int)AxisName.Axis3);
  1819. ret = Math.Abs(x1 - confMgr.LoadPoint_X1) < 1;
  1820. ret = ret & Math.Abs(x2 - confMgr.LoadPoint_X2) < 1;
  1821. ret = ret & Math.Abs(y - confMgr.LoadPoint_Y) < 1;
  1822. ret = ret & Math.Abs(z - confMgr.LoadPoint_Z) < 1;
  1823. return ret;
  1824. }
  1825. #endregion
  1826. #region 张力操作
  1827. /// <summary>
  1828. /// 读取张力数据
  1829. /// </summary>
  1830. /// <returns></returns>
  1831. public double TensionGetValue(out TensionResult tensionResult)
  1832. {
  1833. tensionResult = new TensionResult(0, 0, 0, Color.Empty, Color.Empty, Color.Empty);
  1834. if (confMgr.SysConfigParams.DisableTensor)
  1835. {
  1836. Log("张力读取", "张力设备禁用,忽略此步骤!");
  1837. return -1;
  1838. }
  1839. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.触发张力按钮灯), GetIOBitIndex((int)DOName.触发张力按钮灯), true);
  1840. double tensionValue = 0;
  1841. for (int i = 0; i < 5; i++)
  1842. {
  1843. tensionValue = tensionDev.GetValue() + confMgr.SysConfigParams.Tension_Offset;//加入张力偏差
  1844. tensionValue = Math.Round(tensionValue, 2);//保留2位小数
  1845. if (tensionValue >= 0)
  1846. break;
  1847. }
  1848. if (tensionValue < 0)
  1849. {
  1850. Log("张力读取", "张力读取失败,忽略此次测试!");
  1851. return -1;
  1852. }
  1853. Log("张力读取", $"张力值:{tensionValue}");
  1854. Thread.Sleep(500);
  1855. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.触发张力按钮灯), GetIOBitIndex((int)DOName.触发张力按钮灯), false);
  1856. lstTension.Add(tensionValue);
  1857. if (lstTension.Count == 1)
  1858. order.Tension1 = tensionValue;
  1859. else if (lstTension.Count == 2)
  1860. order.Tension2 = tensionValue;
  1861. else if (lstTension.Count == 3)
  1862. order.Tension3 = tensionValue;
  1863. else if (lstTension.Count == 4)
  1864. order.Tension4 = tensionValue;
  1865. else if (lstTension.Count == 5)
  1866. order.Tension5 = tensionValue;
  1867. //TensionResult tensionResult;
  1868. if (CurrProductModel != null)
  1869. updateTensionValue(CurrProductModel.TensionBaseValue + CurrProductModel.TensionUpFloatValue, CurrProductModel.TensionBaseValue - CurrProductModel.TensionDownFloatValue, out tensionResult);
  1870. return tensionValue;
  1871. }
  1872. /// <summary>
  1873. /// 新流程联动读取张力
  1874. /// </summary>
  1875. /// <returns></returns>
  1876. public double TensionGetValueNewStep()
  1877. {
  1878. double tensionValue = 0;
  1879. for (int cnt = 0; cnt < 2; cnt++)
  1880. {
  1881. for (int i = 0; i < 10; i++)
  1882. {
  1883. tensionValue = tensionDev.GetValue() + confMgr.SysConfigParams.Tension_Offset;//加入张力偏差
  1884. tensionValue = Math.Round(tensionValue, 2);//保留2位小数
  1885. if (tensionValue >= 0)
  1886. break;
  1887. Thread.Sleep(50);
  1888. }
  1889. //成功读取跳出循环
  1890. if (tensionValue >= 0)
  1891. break;
  1892. else
  1893. {
  1894. //重连
  1895. tensionDev.CloseDev();
  1896. Thread.Sleep(100);
  1897. if (tensionDev.OpenDevByCom(confMgr.SysConfigParams.TensionCom, confMgr.SysConfigParams.TensionComBaud) < 0)
  1898. {
  1899. Log("张力传感器重连失败!", "重连", WarningEnum.High);
  1900. return -10;
  1901. }
  1902. }
  1903. }
  1904. if (tensionValue < 0)
  1905. {
  1906. return -1;
  1907. }
  1908. return tensionValue;
  1909. }
  1910. public class TensionResult
  1911. {
  1912. public double value = 0;
  1913. public double valueMax = 0;
  1914. public double valueMin = 0;
  1915. public Color color = Color.Empty;
  1916. public Color colorMax = Color.Empty;
  1917. public Color colorMin = Color.Empty;
  1918. public TensionResult(double val, double valMax, double valMin, Color clr, Color clrMax, Color clrMin) {
  1919. value = val; valueMax = valMax; valueMin = valMin; color = clr; colorMax = clrMax; colorMin = clrMin;
  1920. }
  1921. }
  1922. private void updateTensionValue(double upperLimit, double lowerLimit, out TensionResult tensionResult)
  1923. {
  1924. int count = lstTension.Count();
  1925. tensionResult = new TensionResult(0,0,0, Color.Empty, Color.Empty, Color.Empty);
  1926. if (count < 1) return;
  1927. switch (count)
  1928. {
  1929. case 1:
  1930. order.Tension1 = lstTension[count - 1];
  1931. Log("张力值", $"张力1:{order.Tension1}");
  1932. break;
  1933. case 2:
  1934. order.Tension2 = lstTension[count - 1];
  1935. Log("张力值", $"张力2:{order.Tension2}");
  1936. break;
  1937. case 3:
  1938. order.Tension3 = lstTension[count - 1];
  1939. Log("张力值", $"张力3:{order.Tension3}");
  1940. break;
  1941. case 4:
  1942. order.Tension4 = lstTension[count - 1];
  1943. Log("张力值", $"张力4:{order.Tension4}");
  1944. break;
  1945. case 5:
  1946. order.Tension5 = lstTension[count - 1];
  1947. Log("张力值", $"张力5:{order.Tension5}");
  1948. break;
  1949. }
  1950. double value = Math.Round(lstTension.Average(), 2);
  1951. double valueMax = lstTension.Max();
  1952. double valueMin = lstTension.Min();
  1953. if (order != null) order.TensionValue = value;
  1954. Color color = (upperLimit + lowerLimit > 0 && (value > upperLimit || value < lowerLimit)) ? Color.Red : Color.White;
  1955. Color colorMax = (upperLimit + lowerLimit > 0 && (valueMax > upperLimit || valueMax < lowerLimit)) ? Color.Red : Color.White;
  1956. Color colorMin = (upperLimit + lowerLimit > 0 && (valueMin > upperLimit || valueMin < lowerLimit)) ? Color.Red : Color.White;
  1957. tensionResult = new TensionResult(value, valueMax, valueMin, color, colorMax, colorMin);
  1958. //不合格
  1959. if (color == Color.Red) order.Qualified = false;
  1960. }
  1961. #endregion
  1962. #region 修复台照片删除
  1963. /// <summary>
  1964. /// 删除修复台重复sn图片
  1965. /// </summary>
  1966. private void DeleteRepairImage(string sn)
  1967. {
  1968. //删除文件
  1969. Task.Factory.StartNew(() =>
  1970. {
  1971. string dirPath = Util.CreateSubDir(confMgr.SysConfigParams.SizeRepairImag.SavePath,
  1972. new List<string> { DateTime.Now.ToString("yyyyMMdd"), sn });
  1973. if (!Directory.Exists(dirPath))
  1974. {
  1975. return;
  1976. }
  1977. string[] array = Directory.GetFiles(dirPath);
  1978. foreach (string text in array)
  1979. {
  1980. try
  1981. {
  1982. API.OutputDebugString("清除文件:" + text + "...");
  1983. File.Delete(text);
  1984. }
  1985. catch (Exception ex)
  1986. {
  1987. API.OutputDebugString("Ex1:" + ex.Message);
  1988. }
  1989. }
  1990. dirPath = Util.CreateSubDir(confMgr.SysConfigParams.DefectRepairImag.SavePath,
  1991. new List<string> { DateTime.Now.ToString("yyyyMMdd"), sn });
  1992. if (!Directory.Exists(dirPath))
  1993. {
  1994. return;
  1995. }
  1996. array = Directory.GetFiles(dirPath);
  1997. foreach (string text in array)
  1998. {
  1999. try
  2000. {
  2001. API.OutputDebugString("清除文件:" + text + "...");
  2002. File.Delete(text);
  2003. }
  2004. catch (Exception ex)
  2005. {
  2006. API.OutputDebugString("Ex1:" + ex.Message);
  2007. }
  2008. }
  2009. });
  2010. }
  2011. #endregion
  2012. #region 启动
  2013. /// <summary>
  2014. /// 自动运行
  2015. /// </summary>
  2016. /// <returns></returns>
  2017. public bool StartRun(Form fatherFrm, string detectOrder, int defectCnt, string productCode, string sn)
  2018. {
  2019. bool ret = true;
  2020. //Log("运行", $"启动自动检测流程---料号:{productCode},网版编码:{sn}");
  2021. //运行前清除过期图片文件
  2022. //DateTime st = DateTime.Now;
  2023. DelectPictureFile();
  2024. if(CurrProcessIndex < -1)
  2025. {
  2026. Log("运行", "流程报警中,请清除报警,复位启动", WarningEnum.Low);
  2027. return false;
  2028. }
  2029. if ((statusMgr.Status != SystemStsEnum.Standby)&&(statusMgr.Status != SystemStsEnum.Pause))
  2030. {
  2031. Log("运行", "系统非可运行状态", WarningEnum.Low);
  2032. return false;
  2033. }
  2034. //Log("启动", "移动至上料位...");
  2035. //GotoLoadPos();
  2036. if (!CheckPosIsLoadPos())
  2037. {
  2038. Log("运行", "载具不在上料位!请复位到上料位在启动!", WarningEnum.Low);
  2039. FrmDialog.ShowDialog(fatherFrm, $"载具不在上料位!请复位到上料位在启动!", "警告", false);
  2040. return false;
  2041. }
  2042. if (string.IsNullOrEmpty(productCode))
  2043. {
  2044. Log("运行", "产品料号未选择!", WarningEnum.Low);
  2045. return false;
  2046. }
  2047. string code = productCode;
  2048. //清空显示
  2049. //scannerGBmpQueue.Clear();
  2050. scannerCBmpQueue.Clear();
  2051. scannerGBmpQueue.Clear();
  2052. lstCompareFailZoomImage.Clear();
  2053. contoursAffineTrans1_Out = null;
  2054. //情况流程记录数据
  2055. ProductPT_HeightBaseNum = 0;
  2056. lstHeight.Clear();
  2057. lstHeightBase.Clear();
  2058. lstLineWidth.Clear();
  2059. lstTension.Clear();
  2060. lstPT.Clear();
  2061. lstTestData.Clear();
  2062. //清空打印内容
  2063. CurrPrintInfos.Clear();
  2064. //Log("调试", $"time1:{(DateTime.Now - st).Milliseconds}");
  2065. //st = DateTime.Now;
  2066. int errStep = 0;
  2067. try
  2068. {
  2069. var model = PdtService.GetModelNav(code);
  2070. if (model != null && model.StepInfo != null && model.StepInfo.ProcessList.Count > 0)
  2071. {
  2072. errStep = 1;
  2073. //根据产品设置动态加载外观检测模型文件
  2074. string onnxFile;
  2075. if (!string.IsNullOrWhiteSpace(model.DefectModelFile))
  2076. onnxFile = $"{ConfMgr.Instance.SysConfigParams.AIModelPath}\\{model.DefectModelFile}";
  2077. else
  2078. onnxFile = $"{ConfMgr.Instance.SysConfigParams.AIModelPath}\\default.onnx";
  2079. errStep = 2;
  2080. defectLib.loadModelFile(onnxFile);
  2081. errStep = 3;
  2082. //判断检测工单号
  2083. if (confMgr.SysConfigParams.OpenOredrCheck && string.IsNullOrWhiteSpace(detectOrder))
  2084. {
  2085. if (FrmDialog.ShowDialog(fatherFrm, $"检测工单为空是否继续?", "提示", true) != DialogResult.OK)
  2086. {
  2087. Log("运行", "检测工单号为空!", WarningEnum.Low);
  2088. return false;
  2089. }
  2090. else
  2091. Log("运行", "检测工单号为空测试");
  2092. }
  2093. //判定检测工单数量
  2094. if (confMgr.SysConfigParams.OpenOredrCntCheck)
  2095. {
  2096. var detectOrderList = OrderService.GetListNav(detectOrder);
  2097. if (detectOrderList != null && detectOrderList.Count >= defectCnt)
  2098. {
  2099. if (FrmDialog.ShowDialog(fatherFrm, $"检测工单数量已满 {detectOrderList.Count} 是否继续?", "提示", true) != DialogResult.OK)
  2100. {
  2101. Log("运行", "检测工单数量已满!", WarningEnum.Low);
  2102. return false;
  2103. }
  2104. else
  2105. Log("运行", "检测工单数量已满,继续测试");
  2106. }
  2107. }
  2108. //输入SN
  2109. if (string.IsNullOrWhiteSpace(sn))
  2110. {
  2111. Log("运行", "网版编码为空!", WarningEnum.Low);
  2112. return false;
  2113. }
  2114. Log("运行", $"料号:{code},网版编码:{sn}");
  2115. //记忆sn
  2116. //Remind(sn);
  2117. //查询SN是否重复
  2118. var findSN = OrderService.GetModelNav(sn);
  2119. errStep = 4;
  2120. if ((findSN != null)&&(findSN.ProductInfo.Code == model.Code))
  2121. {
  2122. Log("运行", $"网版编码:{sn}, 已经存在检测数据!");
  2123. if(FrmDialog.ShowDialog(fatherFrm, $"网版编码:{sn}, 已经存在检测数据!", "提示", true) != DialogResult.OK)
  2124. {
  2125. Log("运行", "网版编码重复测试终止运行!", WarningEnum.Low);
  2126. return false;
  2127. }
  2128. else
  2129. Log("运行", "网版编码重复测试");
  2130. //删除已有sn的修复图片
  2131. DeleteRepairImage(sn);
  2132. }
  2133. //Log("调试", $"time3:{(DateTime.Now - st).Milliseconds}");
  2134. //st = DateTime.Now;
  2135. errStep = 5;
  2136. //判断SN数量是否达到批次上限
  2137. //创建表达式
  2138. if (!string.IsNullOrWhiteSpace(model.BatchId) && model.TargetCount > 0)
  2139. {
  2140. var exp1 = Expressionable.Create<Order>()
  2141. .And(m => m.ProductId == model.Id)
  2142. .And(m => m.BatchId == model.BatchId)
  2143. .And(m => m.SN != sn)
  2144. .ToExpression();//注意 这一句 不能少
  2145. errStep = 6;
  2146. if (OrderService.Count(exp1) >= model.TargetCount)
  2147. {
  2148. Log("运行", $"当前产品本批次检测数已达目标数量,请更换检测批次号!", WarningEnum.Low);
  2149. return false;
  2150. }
  2151. errStep = 7;
  2152. }
  2153. //判断是否清空工单打印的数据
  2154. if(model.EnableOrderPrint)
  2155. {
  2156. CurrDefectOrders = OrderService.GetListNav(detectOrder);
  2157. if (CurrDefectOrders == null || CurrDefectOrders.Count == 0)
  2158. {
  2159. Log("运行", "当前工单未测试,清空所有工单数据!");
  2160. CurrOrderPrintInfos.Clear();
  2161. CurrDefectIndex = 0;
  2162. }
  2163. else
  2164. {
  2165. CurrDefectIndex = CurrDefectOrders.Count;
  2166. }
  2167. Log("运行", $"当前工单第{CurrDefectIndex + 1}块,开始测试!");
  2168. }
  2169. //Log("调试", $"time4:{(DateTime.Now - st).Milliseconds}");
  2170. //st = DateTime.Now;
  2171. //界面显示SN
  2172. model.HeightBaseDec = "";
  2173. CurrProductModel = model;
  2174. Log("运行", $"{model.Name} {model.Spec} [{model.Code}]");
  2175. //新旧流程判断
  2176. if (model.StepInfo.ProcessType != "快速流程")
  2177. {
  2178. IsNewStepProcessVel = false;
  2179. OnAutoRuning(new RunEventArgs(sn, model.StepInfo.ProcessList));
  2180. }
  2181. else
  2182. {
  2183. IsNewStepProcessVel = true;
  2184. OnAutoRuning(new RunEventArgs(sn, model.StepInfo.ProcessList, true));
  2185. }
  2186. forLib.clear();
  2187. ifLib.clear();
  2188. TotalCnt = defectCnt;
  2189. errStep = 8;
  2190. order = new Order();
  2191. order.Qualified = true;//默认合格,中间有一项指标不合格则改为false
  2192. order.ProductId = CurrProductModel.Id;
  2193. order.StepId = (int)CurrProductModel.StepId;
  2194. order.XPTValue = 0;
  2195. order.DetectOrder = detectOrder;
  2196. order.OrderCode = productCode;
  2197. order.SN = sn;
  2198. order.BatchId = CurrProductModel.BatchId;
  2199. errStep = 9;
  2200. AllDefectCount = 0;
  2201. SizeNGCnt = 0;
  2202. defectBmpNumResult = defectBmpNum = compBmpNum = compBmpIndex = 0;
  2203. IsCurrHeightBase = false;
  2204. //加载产品需要打印的内容
  2205. if (model.PrintInfoList != null)
  2206. CurrPrintInfos = new List<PrintInfo>(model.PrintInfoList.ToArray()); // copy
  2207. if (model.EnableOrderPrint && model.PrintInfoList != null && CurrOrderPrintInfos.Count == 0)
  2208. {
  2209. Log("运行", $"获取打印工单信息{CurrDefectIndex}!");
  2210. CurrOrderPrintInfos = new List<PrintInfo>(model.PrintInfoList.ToArray()); // copy
  2211. }
  2212. //RunQG(true);
  2213. //新流程判断是否测厚度,是的话开启基准检测
  2214. if (IsNewStepProcessVel)
  2215. {
  2216. bool openHeightBaseTest = false;
  2217. string baseParams = "";
  2218. string processName = "";
  2219. foreach (var item in model.StepInfo.ProcessList)
  2220. {
  2221. if((item.ProcessCode == "Height")&&(!confMgr.SysConfigParams.DisableThickness))
  2222. {
  2223. processName = item.ProcessName;
  2224. baseParams = item.ProcessParams;
  2225. ThicknessProp Param = JsonConvert.DeserializeObject<ThicknessProp>(item.ProcessParams);
  2226. openHeightBaseTest = !Param.Disable;
  2227. break;
  2228. }
  2229. }
  2230. if (openHeightBaseTest)
  2231. {
  2232. if (SizeEnable)
  2233. {
  2234. if (HeightProcessTest(0, processName, baseParams, true) < 0)
  2235. return false;
  2236. }
  2237. }
  2238. }
  2239. //Log("启动", "8");
  2240. IsGetStartSig = false;
  2241. CurrProcessIndex = 0;
  2242. CurrPoinntCount = 0;
  2243. CurrStepResult = 0;
  2244. LedRun();
  2245. stopWatch = new Stopwatch();
  2246. _isRuning = true;
  2247. _isAuto = true;
  2248. statusMgr.GotoAuto();
  2249. SendStatus();
  2250. errStep = 10;
  2251. //Log("调试", $"time5:{(DateTime.Now - st).Milliseconds}");
  2252. //st = DateTime.Now;
  2253. //调试,可删
  2254. //CurrDefectOrders = OrderService.GetListNav(order.DetectOrder);
  2255. //if (model.EnableOrderPrint && (CurrDefectOrders.Count == TotalCnt))
  2256. //{
  2257. // Log("工单打印", $"打印机:{confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.OrderTempPath}");
  2258. // ret = PrintFileOrderData(confMgr.SysConfigParams.ExcelPrinterName,
  2259. // model.OrderTempPath, CurrOrderPrintInfos, model);
  2260. // if (ret)
  2261. // Log("工单打印", $"打印成功!");
  2262. // else
  2263. // Log("工单打印", $"打印失败:打印机={confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.OrderTempPath}, 打印数据={CurrOrderPrintInfos}", WarningEnum.Low);
  2264. //}
  2265. }
  2266. else
  2267. Log("运行", model != null ? $"料号{code}不存在!" : $"产品({model.Name})未配置检测流程!", WarningEnum.Low);
  2268. }
  2269. catch (Exception ex)
  2270. {
  2271. Log("运行", $"程序错误-{errStep}:" + ex.Message + "\n", WarningEnum.High);
  2272. }
  2273. return ret;
  2274. }
  2275. /// <summary>
  2276. /// 暂停重启
  2277. /// </summary>
  2278. /// <returns></returns>
  2279. public bool ReStartRun()
  2280. {
  2281. bool ret = false;
  2282. if (CurrProcessIndex >= 1 )
  2283. {
  2284. Log("启动", $"暂停 -> 继续 当前工序索引:{CurrProcessIndex + 1}");
  2285. LedRun();
  2286. _isRuning = true;
  2287. statusMgr.GotoAuto();
  2288. SendStatus();
  2289. ret = true;
  2290. }
  2291. return ret;
  2292. }
  2293. #endregion
  2294. #region 报警等、按钮IO
  2295. /// <summary>
  2296. /// 三色灯报警状态显示
  2297. /// </summary>
  2298. /// <returns></returns>
  2299. public bool WarningShowLed(bool DisEnableBuzz)
  2300. {
  2301. bool sts = false;
  2302. if (statusMgr.Warning == WarningEnum.Normal)
  2303. {
  2304. if(statusMgr.Status == SystemStsEnum.Auto)
  2305. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), true);
  2306. else
  2307. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  2308. if (statusMgr.Status == SystemStsEnum.Pause)
  2309. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), true);
  2310. else
  2311. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), false);
  2312. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  2313. BuzzCnt = 0;
  2314. //判断黄灯是否需要闪烁,调用200ms一次
  2315. if (Blink)
  2316. {
  2317. if(BlinkCnt < 3)
  2318. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), true);
  2319. else if(BlinkCnt < 6)
  2320. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), false);
  2321. BlinkCnt++;
  2322. if (BlinkCnt == 6)
  2323. BlinkCnt = 0;
  2324. }
  2325. else
  2326. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), false);
  2327. }
  2328. if (statusMgr.Warning == WarningEnum.Low)
  2329. {
  2330. //ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  2331. //ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), true);
  2332. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), true);
  2333. //ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  2334. //sts = true;
  2335. }
  2336. if (statusMgr.Warning == WarningEnum.High)
  2337. {
  2338. sts = true;
  2339. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  2340. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), true);
  2341. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), true);
  2342. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  2343. if (confMgr.SysConfigParams.OpenBuzzer && !DisEnableBuzz)
  2344. {
  2345. if(BuzzCnt < 3)
  2346. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), true);
  2347. else if (BuzzCnt < 6)
  2348. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  2349. BuzzCnt++;
  2350. if (BuzzCnt == 6)
  2351. BuzzCnt = 0;
  2352. }
  2353. }
  2354. return sts;
  2355. }
  2356. /// <summary>
  2357. /// 按钮IO检测
  2358. /// </summary>
  2359. /// <returns></returns>
  2360. public int ButtonIOTrg(bool DisEnableDoorAlm)
  2361. {
  2362. int ret = 0;
  2363. bool sts;
  2364. if(confMgr.SysConfigParams.OpenDoor && !DisEnableDoorAlm)
  2365. {
  2366. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.门磁), GetIOBitIndex((int)DIName.门磁), out sts);
  2367. if ((!sts)&&(statusMgr.Status == SystemStsEnum.Auto))
  2368. {
  2369. Log("暂停", "门磁报警-门打开", WarningEnum.Low );
  2370. statusMgr.GotoPause();
  2371. SendStatus();
  2372. ret = 2;
  2373. }
  2374. }
  2375. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.暂停按钮), GetIOBitIndex((int)DIName.暂停按钮), out sts);
  2376. if (sts)
  2377. {
  2378. Log("暂停", "手动暂停");
  2379. statusMgr.GotoPause();
  2380. SendStatus();
  2381. ret = 2;
  2382. }
  2383. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.复位按钮), GetIOBitIndex((int)DIName.复位按钮), out sts);
  2384. if (sts)
  2385. {
  2386. ret = 3;
  2387. //if (SysMgr.Instance.StatusMgr.Status == SystemStsEnum.Warning)
  2388. //{
  2389. // Log("清除", "手动清除报警");
  2390. // if (SysMgr.Instance.IsAuto)
  2391. // SysMgr.Instance.StatusMgr.GotoPause();
  2392. // else
  2393. // SysMgr.Instance.StatusMgr.GotoNormalStandby();
  2394. //}
  2395. }
  2396. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.启动按钮), GetIOBitIndex((int)DIName.启动按钮), out sts);
  2397. if (sts)
  2398. ret = 1;
  2399. //张力触发按钮
  2400. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.触发张力), GetIOBitIndex((int)DIName.触发张力), out sts);
  2401. if ((sts) && (!IsNewStepProcessVel))
  2402. ret = 4;
  2403. else if ((sts) && (IsNewStepProcessVel))
  2404. {
  2405. ret = 5;
  2406. }
  2407. return ret ;
  2408. }
  2409. #endregion
  2410. #region 手动回原
  2411. /// <summary>
  2412. /// 设备硬件重新加载
  2413. /// </summary>
  2414. public void AllResetAndGoHome()
  2415. {
  2416. try
  2417. {
  2418. Log("复位", "系统硬件重置-关闭");
  2419. if(_isInit)
  2420. lensMotorDev.CloseBoard();
  2421. _isInit = false;
  2422. _isAuto = false;
  2423. _isRuning = false;
  2424. statusMgr.ClearWarning();
  2425. AxisDStop();
  2426. axisDev.CloseBoard();
  2427. ioCardDev.ResetAllDO();
  2428. ioCardDev.CloseBoard();
  2429. lightDev.CloseDev();
  2430. thicknessDev.CloseDev();
  2431. tensionDev.CloseDev();
  2432. //Thread.Sleep(500);
  2433. System.GC.Collect();
  2434. for (int i = 0; i < 30; i++)
  2435. {
  2436. System.Windows.Forms.Application.DoEvents();
  2437. Thread.Sleep(100);
  2438. }
  2439. //System.Windows.Forms.Application.DoEvents();
  2440. //Thread.Sleep(500);
  2441. //System.Windows.Forms.Application.DoEvents();
  2442. //Thread.Sleep(500);
  2443. //System.Windows.Forms.Application.DoEvents();
  2444. lensMotorDev = new PmsMotion();
  2445. camDevFront.CloseCamera();
  2446. camDevFront = new CamDev(SysUseCamFront, confMgr.SysConfigParams.FrontCamName, confMgr.SysConfigParams.FrontCamCfgPath);
  2447. camDevBack.CloseCamera();
  2448. camDevBack = new CamDev(SysUseCamBack, confMgr.SysConfigParams.BackCamName, confMgr.SysConfigParams.BackCamCfgPath);
  2449. Log("复位", "系统硬件重置-初始化");
  2450. Log("复位", "IO板卡初始化");
  2451. if (ioCardDev.InitBoard(MaiMuControl.Device.IOBordType.Advantech) < 0)
  2452. {
  2453. Log("IO板卡初始化失败!", "初始化", WarningEnum.High);
  2454. return;
  2455. }
  2456. if (ioCardDev.OpenBoard(confMgr.SysConfigParams.IODevName, confMgr.SysConfigParams.IOCfgPath) < 0)
  2457. {
  2458. Log("打开IO板卡失败!", "初始化", WarningEnum.High);
  2459. return;
  2460. }
  2461. if (ioCardDev.ResetAllDO() < 0)
  2462. {
  2463. Log("IO Reset失败!", "初始化", WarningEnum.High);
  2464. return;
  2465. }
  2466. statusMgr.GotoInitial();
  2467. SendStatus();
  2468. statusMgr.ClearWarning();
  2469. _isInit = true;
  2470. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.复位按钮黄灯), GetIOBitIndex((int)DOName.复位按钮黄灯), true);
  2471. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯黄灯), GetIOBitIndex((int)DOName.三色灯黄灯), true);
  2472. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯绿灯), GetIOBitIndex((int)DOName.三色灯绿灯), false);
  2473. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯红灯), GetIOBitIndex((int)DOName.三色灯红灯), false);
  2474. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.三色灯蜂鸣器), GetIOBitIndex((int)DOName.三色灯蜂鸣器), false);
  2475. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.启动按钮绿灯), GetIOBitIndex((int)DOName.启动按钮绿灯), false);
  2476. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.停止按钮红灯), GetIOBitIndex((int)DOName.停止按钮红灯), false);
  2477. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  2478. //电机初始化
  2479. Log("复位", "运动控制板卡初始化");
  2480. if (axisDev.InitBoard() < 0)
  2481. {
  2482. Log("运动控制板卡初始化失败!", "初始化", WarningEnum.High);
  2483. return;
  2484. }
  2485. if (axisDev.OpenBoard(0, confMgr.SysConfigParams.MotionCfgPath) < 0)
  2486. {
  2487. Log("打开运动控制板卡失败!", "初始化", WarningEnum.High);
  2488. return;
  2489. }
  2490. if (axisDev.LoadBoardParams(0, boardCfgParams) < 0)
  2491. {
  2492. Log("载入运动控制板卡参数失败1!", "初始化", WarningEnum.High);
  2493. return;
  2494. }
  2495. //光源初始化
  2496. Log("复位", "光源控制器初始化");
  2497. int com_num = int.Parse(confMgr.SysConfigParams.LightCom.Remove(0, 3));
  2498. if (lightDev.InitDev(com_num, confMgr.SysConfigParams.LightComBaud) < 0)
  2499. {
  2500. Log("光源控制器初始化失败!", "初始化", WarningEnum.High);
  2501. return;
  2502. }
  2503. //张力传感器初始化
  2504. Log("复位", "张力传感器初始化");
  2505. if (tensionDev.OpenDevByCom(confMgr.SysConfigParams.TensionCom, confMgr.SysConfigParams.TensionComBaud) < 0)
  2506. {
  2507. Log("张力传感器初始化失败!", "初始化", WarningEnum.High);
  2508. return;
  2509. }
  2510. //InitLog("初始化张力传感器成功!");
  2511. //镜头电机初始化
  2512. Log("复位", "镜头电机初始化");
  2513. lensMotorDev.InitBoard();
  2514. if (lensMotorDev.OpenBoardByCom(confMgr.SysConfigParams.LensMotorCom, confMgr.SysConfigParams.LensMotorComBaud) < 0)
  2515. {
  2516. Log("镜头电机初始化失败!", "初始化", WarningEnum.High);
  2517. return;
  2518. }
  2519. //测厚传感器初始化
  2520. Log("复位", "测厚传感器初始化");
  2521. if (thicknessDev.OpenDevByTcp(confMgr.SysConfigParams.ThicknessIP, confMgr.SysConfigParams.ThicknessPort) < 0)
  2522. {
  2523. Log("测厚传感器初始化失败!", "初始化", WarningEnum.High);
  2524. return;
  2525. }
  2526. //相机初始化
  2527. Log("复位", "前部相机初始化");
  2528. if (!camDevFront.InitCamera())
  2529. {
  2530. Log("前部相机初始化失败!", "初始化", WarningEnum.High);
  2531. return;
  2532. }
  2533. if (!camDevFront.OpenCamera())
  2534. {
  2535. Log("前部相机打开失败!", "初始化", WarningEnum.High);
  2536. return;
  2537. }
  2538. Log("复位", "后部相机初始化");
  2539. if (!camDevBack.InitCamera())
  2540. {
  2541. Log("后部相机初始化失败!", "初始化", WarningEnum.High);
  2542. return;
  2543. }
  2544. if (!camDevBack.OpenCamera())
  2545. {
  2546. Log("后部相机打开失败!", "初始化", WarningEnum.High);
  2547. return;
  2548. }
  2549. Log("复位", "系统硬件重置-回原");
  2550. //镜头电机回原
  2551. lensMotorDev.BackHome(0, new HomeVelocityParams());
  2552. lensMotorDev.CheckHomeDone(0, 3000);
  2553. //移动到 4.5X
  2554. //lensMotorDev.MoveAbsPulse(0, new VelocityCurveParams(), (int)SmallAxCmdPos.倍率4_5X);
  2555. //lensMotorDev.CheckDone(0, 5000);
  2556. //移动Axis前等待厚度传感器收回
  2557. if (thicknessDev.GetValue() < Math.Abs(confMgr.SysConfigParams.ThicknessSafeValue))
  2558. {
  2559. Log("厚度传感器不在安全位置!", "初始化", WarningEnum.High);
  2560. return;
  2561. }
  2562. //多轴回原
  2563. if ((homeParamsZ != null) && (homeParamsX1 != null) && (homeParamsX2 != null) && (homeParamsY != null))
  2564. {
  2565. axisDev.ResetAxisState((int)AxisName.Axis0);
  2566. axisDev.ResetAxisState((int)AxisName.Axis1);
  2567. axisDev.ResetAxisState((int)AxisName.Axis2);
  2568. axisDev.ResetAxisState((int)AxisName.Axis3);
  2569. Log("复位", "Z轴开始回原点...");
  2570. axisDev.BackHome((int)AxisName.Axis3, homeParamsZ);
  2571. Log("复位", "X1轴开始回原点...");
  2572. axisDev.BackHome((int)AxisName.Axis0, homeParamsX1);
  2573. Log("复位", "X2轴开始回原点...");
  2574. axisDev.BackHome((int)AxisName.Axis1, homeParamsX1);
  2575. Log("复位", "Y轴开始回原点...");
  2576. //y轴使用io回原
  2577. AxisYGoHome();
  2578. }
  2579. Thread.Sleep(1000);
  2580. //判断轴是否回原成功
  2581. if (!AxisYGoHomeDone(60))
  2582. {
  2583. AxisAllImmediateStop();
  2584. Log("复位", "Y轴回原失败", WarningEnum.High);
  2585. return;
  2586. }
  2587. if (axisDev.CheckHomeDone((int)AxisName.Axis0, 60) != 0)
  2588. {
  2589. AxisAllImmediateStop();
  2590. Log("复位", "X1轴回原失败", WarningEnum.High);
  2591. return;
  2592. }
  2593. if (axisDev.CheckHomeDone((int)AxisName.Axis1, 60) != 0)
  2594. {
  2595. AxisAllImmediateStop();
  2596. Log("复位", "X2轴回原失败", WarningEnum.High);
  2597. return;
  2598. }
  2599. if (axisDev.CheckHomeDone((int)AxisName.Axis3, 60) != 0)
  2600. {
  2601. AxisAllImmediateStop();
  2602. Log("复位", "Z轴回原失败", WarningEnum.High);
  2603. return;
  2604. }
  2605. Log("复位", "所有轴回原成功!");
  2606. //清空y轴发送命令和反馈位置
  2607. axisDev.SetCommandPos((int)AxisName.Axis2, 0);
  2608. axisDev.SetFeedbackPos((int)AxisName.Axis2, 0);
  2609. //X轴标定启用
  2610. if (confMgr.SysConfigParams.OpenAxisXCalibration)
  2611. {
  2612. OpenAxisXCal();
  2613. }
  2614. Log("复位", "移动到上料...");
  2615. //Thread.Sleep(1000);
  2616. LedReady();
  2617. GotoLoadPos();
  2618. //初始化成功
  2619. _isInit = true;
  2620. statusMgr.GotoNormalStandby();
  2621. SendStatus();
  2622. }
  2623. catch (Exception e)
  2624. {
  2625. _isInit = false;
  2626. Log("复位", $"重置失败:{e.Message}", WarningEnum.High);
  2627. }
  2628. }
  2629. #endregion
  2630. #region 位置获取
  2631. public string GetAxisPos()
  2632. {
  2633. string posStrng = "";
  2634. double pos1 = axisDev.GetFeedbackPos((int)AxisName.Axis0);
  2635. double pos2 = axisDev.GetFeedbackPos((int)AxisName.Axis1);
  2636. double pos3 = axisDev.GetFeedbackPos((int)AxisName.Axis2);
  2637. double pos4 = axisDev.GetFeedbackPos((int)AxisName.Axis3);
  2638. double cmd1 = axisDev.GetCommandPos((int)AxisName.Axis0);
  2639. double cmd2 = axisDev.GetCommandPos((int)AxisName.Axis1);
  2640. double cmd3 = axisDev.GetCommandPos((int)AxisName.Axis2);
  2641. double cmd4 = axisDev.GetCommandPos((int)AxisName.Axis3);
  2642. posStrng = "[命令位:" + (cmd1 / (double)GetMMtoPlus(AxisName.Axis0)).ToString("0.0000") +
  2643. " 反馈位:" + (pos1 / (double)GetMMtoPlus(AxisName.Axis0)).ToString("0.0000") + "]" +
  2644. "[命令位:" + (cmd2 / (double)GetMMtoPlus(AxisName.Axis1)).ToString("0.0000") +
  2645. " 反馈位:" + (pos2 / (double)GetMMtoPlus(AxisName.Axis1)).ToString("0.0000") + "]" +
  2646. "[命令位:" + (cmd3 / (double)GetMMtoPlus(AxisName.Axis2)).ToString("0.0000") +
  2647. " 反馈位:" + (pos3 / (double)GetMMtoPlus(AxisName.Axis2)).ToString("0.0000") + "]" +
  2648. "[命令位:" + (cmd4 / (double)GetMMtoPlus(AxisName.Axis3)).ToString("0.0000") +
  2649. " 反馈位:" + (pos4 / (double)GetMMtoPlus(AxisName.Axis3)).ToString("0.0000") + "]";
  2650. return posStrng;
  2651. }
  2652. #endregion
  2653. #endregion
  2654. #region 主流程
  2655. #region 后台
  2656. /// <summary>
  2657. /// 中断工序运行
  2658. /// </summary>
  2659. /// <returns></returns>
  2660. private bool isBreakProcessRun()
  2661. {
  2662. return statusMgr.Status == SystemStsEnum.Pause || statusMgr.Warning == WarningEnum.High ;
  2663. }
  2664. /// <summary>
  2665. /// 后台运行主线程
  2666. /// </summary>
  2667. private void MainThreadFunction()
  2668. {
  2669. while (true)
  2670. {
  2671. try
  2672. {
  2673. if (_cts.IsCancellationRequested)
  2674. break;
  2675. if (IsRuning)
  2676. {
  2677. //暂停开始
  2678. stopWatch.Start();
  2679. do
  2680. {
  2681. CurrProcessIndex = nextProcess(CurrProductModel, CurrProcessIndex);
  2682. } while (CurrProcessIndex >= 0 && !isBreakProcessRun());
  2683. //暂停中断
  2684. stopWatch.Stop();
  2685. _isRuning = false;
  2686. }
  2687. Thread.Sleep(10);
  2688. }
  2689. catch (Exception e)
  2690. {
  2691. _isRuning = false;
  2692. Log("运行报警", "流程运行出错:" + e.Message + "\n", WarningEnum.High);
  2693. }
  2694. }
  2695. }
  2696. #endregion
  2697. #region 缺陷字典
  2698. /// <summary>
  2699. /// 获取缺陷项阈值
  2700. /// </summary>
  2701. /// <param name="m"></param>
  2702. /// <returns></returns>
  2703. private Dictionary<string, float> getProductAreaThreshol(Product m)
  2704. {
  2705. Dictionary<string, float> dic = new Dictionary<string, float>();
  2706. if (!confMgr.SysConfigParams.OpenAsideDefect)
  2707. {
  2708. foreach (var item in m.QualifiedCriterionList)
  2709. dic.Add(item.DefectCode, (float)(item.Size * 25.4 * 25.4 / m.HoleCount / m.HoleCount));//网目 => mm^2
  2710. }
  2711. else
  2712. {
  2713. foreach (var item in m.QualifiedCriterionList)
  2714. dic.Add(item.DefectCode, (float)(item.Size * 25.4 / m.HoleCount));//网目 => mm^2
  2715. }
  2716. //dic.Add(item.DefectCode, (float)(item.Size * 25.4 * 25.4 / m.HoleCount / m.HoleCount));//网目 => mm^2
  2717. //全缺陷项
  2718. //foreach (var item in Enum.GetValues(typeof(DefectCodeEnum)))
  2719. //{
  2720. // var code = EnumExtension.GetEnumDescription((DefectCodeEnum)item);
  2721. // if (!dic.ContainsKey(code))
  2722. // dic.Add(code, 0);
  2723. //}
  2724. var lstDefect = ConfMgr.GetArrayList<DefectCodeEnum>();
  2725. foreach (DictionaryEntry item in lstDefect)
  2726. {
  2727. string code = item.Value.ToString();
  2728. if (!dic.ContainsKey(code))
  2729. dic.Add(code, 0);
  2730. }
  2731. return dic;
  2732. }
  2733. //统计缺陷类型 [["92.7542","80.85799","99.54083","86.05363","dk","0.52"]]
  2734. public void countDefectClass(List<string>[] list)
  2735. {
  2736. string className;
  2737. for (int i = 0; i < list.Length; i++)
  2738. {
  2739. className = list[i][4];
  2740. switch (className)
  2741. {
  2742. case "dk":
  2743. order.DKCount++;
  2744. break;
  2745. case "zw":
  2746. order.ZWCount++;
  2747. break;
  2748. case "gsyc":
  2749. order.GSYCCount++;
  2750. break;
  2751. case "xws":
  2752. order.XWSCount++;
  2753. break;
  2754. case "qk":
  2755. order.QKCount++;
  2756. break;
  2757. case "zk":
  2758. order.ZKCount++;
  2759. break;
  2760. case "pp":
  2761. order.PPCount++;
  2762. break;
  2763. case "hs":
  2764. order.HSCount++;
  2765. break;
  2766. case "yx":
  2767. order.YXCount++;
  2768. break;
  2769. case "xb":
  2770. order.XBCount++;
  2771. break;
  2772. case "sx": //sx 变为 gs
  2773. order.SXCount++;
  2774. break;
  2775. case "ds":
  2776. order.DSCount++;
  2777. break;
  2778. case "gsdl":
  2779. order.GSDLCount++;
  2780. break;
  2781. case "cjdk":
  2782. order.CJDKCount++;
  2783. break;
  2784. default:
  2785. Log($"数据统计", $"错误参数:{className}", WarningEnum.Low);
  2786. break;
  2787. }
  2788. }
  2789. }
  2790. #endregion
  2791. //model.Type=1 系统校正
  2792. /// <summary>
  2793. ///
  2794. /// </summary>
  2795. /// <param name="model"></param>
  2796. /// <param name="stepIndex">0-n</param>
  2797. /// <returns>大于等于0正常工序; -1:结束 -2:异常</returns>
  2798. private int nextProcess(Models.Product model, int stepIndex)
  2799. {
  2800. try
  2801. {
  2802. //记录当前index
  2803. this.CurrProcessIndex = stepIndex;
  2804. OnAutoRuning(new RunEventArgs(stepIndex));
  2805. //判断是否中断或暂停
  2806. if (isBreakProcessRun())
  2807. return stepIndex;
  2808. //开始计时
  2809. if ( model.StepInfo.StartTimeIndex > 0 && model.StepInfo.StartTimeIndex == stepIndex + 1)
  2810. stopWatch.Restart();
  2811. var processtype = model.StepInfo.ProcessType;
  2812. bool IsNewStep = processtype == "快速流程" ? true: false;
  2813. var processList = model.StepInfo.ProcessList;
  2814. var processInfo = processList[stepIndex];
  2815. string processName = processInfo.ProcessName;
  2816. //当前测试点个数
  2817. int TestCnt = 0;
  2818. //AddTextEvent($"{stepIndex + 1}-{processName}", $"工序开始...");
  2819. string jsonParams = null;//配方
  2820. //使用产品配方
  2821. if (model.ProductProcessList != null && model.ProductProcessList.Count > 0)
  2822. {
  2823. ProductProcess productProcessParams = model.ProductProcessList.First(m => m.ProcessCode == processInfo.ProcessCode);
  2824. if (productProcessParams != null)
  2825. {
  2826. jsonParams = productProcessParams.ProcessParams;
  2827. Log($"{stepIndex + 1}-{processName}", $"使用产品专用配方:{jsonParams}");
  2828. }
  2829. }
  2830. //使用流程默认配方
  2831. if (jsonParams == null)
  2832. {
  2833. jsonParams = processInfo.ProcessParams;
  2834. if (jsonParams == null) throw new Exception("配方为null!!");
  2835. if(IsNewStep)
  2836. Log($"{stepIndex + 1}-{processName}", $"使用 快速流程 默认配方:{jsonParams}");
  2837. else
  2838. Log($"{stepIndex + 1}-{processName}", $"使用 高级流程 默认配方:{jsonParams}");
  2839. }
  2840. //加载工序参数
  2841. JObject processParam = JObject.Parse(jsonParams);
  2842. TestCnt = 0;
  2843. bool s_Qualified = true;
  2844. if (!processParam.ContainsKey("Disable") || !processParam.Value<bool>("Disable"))
  2845. {
  2846. if (!IsNewStep)
  2847. {
  2848. #region 老流程/高级流程
  2849. AutoResetEvent endEvent;
  2850. uint sleepPre = processParam.Value<uint>("SleepPre");
  2851. uint sleepLater = processParam.Value<uint>("SleepLater");
  2852. if (sleepPre > 0)
  2853. Thread.Sleep((int)sleepPre);
  2854. double limitThresholdVal, lowerThresholdVal; //Size,Defect
  2855. //======Switch 工序类型
  2856. bool asynRun;
  2857. string gbxBmpPath = "";
  2858. Models.Attachment attachmentFile;
  2859. int liStatocStepIndex = stepIndex;
  2860. switch (processInfo.ProcessCode)
  2861. {
  2862. case "IOCard":
  2863. #region
  2864. var direction = (IODirectionEnum)processParam.Value<int>("Direction");
  2865. if (direction == IODirectionEnum.输入 || direction == IODirectionEnum.输入输出)
  2866. {
  2867. uint IN_Waiting_Timeout = processParam.Value<uint>("IN_Waiting_Timeout");
  2868. Log($"{stepIndex + 1}-{processName}", $"等待I/O输入信号{(IN_Waiting_Timeout > 0 ? $"(超时时长: {IN_Waiting_Timeout})" : "...")}");
  2869. string[] inValue = processParam.Value<JArray>("IN_OP_SHOW").ToObject<List<string>>().ToArray();
  2870. uint inWaitingTime = 0;
  2871. while (true)
  2872. {
  2873. if (isBreakProcessRun())
  2874. return stepIndex;
  2875. byte[] DIData;
  2876. ioCardDev.GetDIByteState(out DIData);
  2877. if (compareIOInput(inValue, DIData))
  2878. break;
  2879. Thread.Sleep(10);
  2880. inWaitingTime += 10;
  2881. if (IN_Waiting_Timeout > 0 && inWaitingTime >= IN_Waiting_Timeout)
  2882. {
  2883. Log($"{stepIndex + 1}-{processName}", $"输入等待超时告警!", WarningEnum.High);
  2884. return stepIndex;
  2885. }
  2886. }
  2887. Log($"{stepIndex + 1}-{processName}", $"I/O输入信号对比完成!");
  2888. }
  2889. if (direction == IODirectionEnum.输出 || direction == IODirectionEnum.输入输出)
  2890. io_output($"{stepIndex + 1}-{processName}", processParam);
  2891. #endregion
  2892. break;
  2893. case "Tension":
  2894. #region
  2895. Log($"{stepIndex + 1}-{processName}", $"忽略不支持流程!");
  2896. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  2897. #endregion
  2898. break;
  2899. case "Height":
  2900. #region
  2901. if (confMgr.SysConfigParams.DisableThickness)
  2902. {
  2903. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  2904. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  2905. break;
  2906. }
  2907. if (!WaitAllAxisDone())//因启用轴异步功能,使用前需等待
  2908. {
  2909. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  2910. return stepIndex;
  2911. }
  2912. limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
  2913. lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
  2914. bool IsRevise = processParam.Value<bool>("IsRevise");
  2915. double relBaseValue = processParam.Value<double>("RelBaseValue"); //配方中相对偏移值
  2916. var heightValue = thicknessDev.GetValue();
  2917. heightValue = Math.Round(heightValue, 2);//保留2位小数
  2918. File.AppendAllText(Directory.GetCurrentDirectory() + "\\厚度测量记录.txt", heightValue + "\r\n");//TEMP
  2919. if (!IsRevise && heightValue < 0)
  2920. {
  2921. Log($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue},异常数据,终止任务!", WarningEnum.High);
  2922. return stepIndex;
  2923. }
  2924. //厚度Base校正
  2925. if (IsRevise)
  2926. {
  2927. var reviseHeight = heightValue + relBaseValue;
  2928. model.HeightBaseDec += reviseHeight + ";";
  2929. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"base值:{reviseHeight} = 厚度值:{heightValue}+偏移值:{relBaseValue}"));
  2930. Log($"{stepIndex + 1}-{processName}", $"base值:{reviseHeight} = 厚度值:{heightValue}+偏移值:{relBaseValue},校正索引队列:{model.HeightBaseDec}");
  2931. }
  2932. else
  2933. {
  2934. Log($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue},base值:{model.HeightBaseDec},偏移值:{relBaseValue},当前base索引:{ProductPT_HeightBaseNum}");
  2935. double heightDev = 0;
  2936. var heightDev_BaseList = model.HeightBaseDec.Split(new char[] { ';', ',' });
  2937. if (heightDev_BaseList.Count() > ProductPT_HeightBaseNum && heightDev_BaseList[ProductPT_HeightBaseNum].Trim() != "")
  2938. heightDev = Convert.ToDouble(heightDev_BaseList[ProductPT_HeightBaseNum].Trim());
  2939. ProductPT_HeightBaseNum++;
  2940. double heightValue2 = Math.Abs(heightDev - heightValue) + relBaseValue;
  2941. heightValue2 = Math.Round(heightValue2, 2);
  2942. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"厚度值:{heightValue2}"));
  2943. lstHeight.Add(heightValue2);
  2944. Log($"厚度值", $"厚度{lstHeight.Count}:{heightValue2}");
  2945. OnAutoRuning(new RunEventArgs(21, lstHeight, model.HeightBaseValue + model.HeightUpFloatValue, model.HeightBaseValue - model.HeightDownFloatValue));
  2946. double HeightValue = Math.Round(lstHeight.Average(), 2);
  2947. if (order != null)
  2948. order.HeightValue = HeightValue;
  2949. if (order != null)
  2950. {
  2951. if (lstHeight.Count == 1)
  2952. order.Height1 = heightValue2;
  2953. else if (lstHeight.Count == 2)
  2954. order.Height2 = heightValue2;
  2955. else if (lstHeight.Count == 3)
  2956. order.Height3 = heightValue2;
  2957. else if (lstHeight.Count == 4)
  2958. order.Height4 = heightValue2;
  2959. else if (lstHeight.Count == 5)
  2960. order.Height5 = heightValue2;
  2961. }
  2962. double HeightUpper = model.HeightBaseValue + model.HeightUpFloatValue;
  2963. double HeightLower = model.HeightBaseValue - model.HeightDownFloatValue;
  2964. if (HeightUpper + HeightLower > 0 && (HeightValue > HeightUpper || HeightValue < HeightLower))
  2965. order.Qualified = false;
  2966. if (limitThresholdVal > 0 && heightValue2 >= limitThresholdVal)
  2967. {
  2968. Log($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue2},达到上限阀值:{limitThresholdVal},请进行下料...", WarningEnum.High);
  2969. CurrProcessIndex = stepIndex + 1;
  2970. return stepIndex;
  2971. }
  2972. else if (lowerThresholdVal > 0 && heightValue2 < lowerThresholdVal)
  2973. {
  2974. Log($"{stepIndex + 1}-{processName}", $"读取数据:{heightValue2},达到下限阀值:{lowerThresholdVal},请进行下料...", WarningEnum.High);
  2975. CurrProcessIndex = stepIndex + 1;
  2976. return stepIndex;
  2977. }
  2978. Log($"{stepIndex + 1}-{processName}", $"厚度值:{heightValue2} (Base值:{heightDev} - 读取数据:{heightValue} + 偏移值:{relBaseValue})");
  2979. }
  2980. #endregion
  2981. break;
  2982. case "Axis":
  2983. #region 多轴后遗留问题:暂停后再启动不知哪几个轴已执行
  2984. JObject processParamTmp = new JObject();
  2985. //兼容旧版单轴
  2986. if (!processParam.ContainsKey("0") && !processParam.ContainsKey("1") && !processParam.ContainsKey("2") && !processParam.ContainsKey("3"))
  2987. {
  2988. processParam.Add("Enable", true);
  2989. processParamTmp.Add(processParam.Value<int>("AxisIndex").ToString(), processParam);
  2990. processParam = processParamTmp;
  2991. }
  2992. //支持多轴移动
  2993. List<int> axisList = new List<int>();
  2994. foreach (var processParamSub in processParam.Properties())
  2995. {
  2996. processParam = processParamSub.Value as JObject;
  2997. Log($"{stepIndex + 1}-{processName}", processParam.ToString());
  2998. if (!processParam.ContainsKey("Disable") || !processParam.Value<bool>("Disable"))
  2999. {
  3000. //asynRun = processParam.Value<bool>("AsynRun");//异步
  3001. int AxisIndex = processParam.Value<int>("AxisIndex");
  3002. axisList.Add(AxisIndex);
  3003. int DeviceType = processParam.Value<int>("DeviceType");
  3004. double VelLow = processParam.Value<double>("VelLow");
  3005. double VelHigh = processParam.Value<double>("VelHigh");
  3006. double Acc = processParam.Value<double>("Acc");
  3007. double Dec = processParam.Value<double>("Dec");
  3008. AxMoveMode MoveMode = (AxMoveMode)processParam.Value<int>("MoveMode");//绝对位置
  3009. double PPUValue = processParam.Value<double>("Value");
  3010. Log($"{stepIndex + 1}-{processName}",
  3011. $"轴{AxisIndex}准备({(MoveMode == AxMoveMode.绝对位置 ? "绝对" : "相对")})运动至{PPUValue}...");
  3012. if (axisDev.CheckDone(AxisIndex, 60) != 0)
  3013. {
  3014. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}到位失败!", WarningEnum.High);
  3015. return stepIndex;
  3016. }
  3017. VelocityCurveParams vel = new VelocityCurveParams(Acc, Dec, VelLow, VelHigh, MotionST, GetMMtoPlus((AxisName)AxisIndex));
  3018. int iret = 0;
  3019. if (MoveMode == AxMoveMode.绝对位置)
  3020. iret = axisDev.MoveAbsValue(AxisIndex, vel, PPUValue);
  3021. else
  3022. iret = axisDev.MoveRelValue(AxisIndex, vel, PPUValue);
  3023. if (iret != 0)
  3024. {
  3025. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndex}运动失败!", WarningEnum.High);
  3026. return stepIndex;
  3027. }
  3028. }
  3029. }
  3030. //多轴同时运行后强制等待各轴完成
  3031. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  3032. if (!WaitAxisDone(axisList))
  3033. {
  3034. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  3035. return stepIndex;
  3036. }
  3037. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  3038. #endregion
  3039. break;
  3040. case "AxisTag":
  3041. #region
  3042. //asynRun = processParam.Value<bool>("AsynRun");//异步
  3043. string axisSizeTag = processParam.Value<string>("SizeTag");
  3044. int useIndex = processParam.Value<int>("UseIndex");//消费posePT中的索引
  3045. AxMoveMode TagMoveMode = (AxMoveMode)processParam.Value<int>("MoveMode");//绝对位置
  3046. var AxisIndexList = processParam.Value<JArray>("AxisIndexList").ToObject<List<int>>();
  3047. double TagVelLow = processParam.Value<double>("VelLow");
  3048. double TagVelHigh = processParam.Value<double>("VelHigh");
  3049. double TagAcc = processParam.Value<double>("Acc");
  3050. double TagDec = processParam.Value<double>("Dec");
  3051. //判断有无tag
  3052. if (order.SizeTagDataList == null)
  3053. {
  3054. Log($"{stepIndex + 1}-{processName}", $"数据提供者Tag为空!", WarningEnum.High);
  3055. return stepIndex;
  3056. }
  3057. var sizeTagObj = order.SizeTagDataList.LastOrDefault(m => m.SizeTag == axisSizeTag);//用最新的last
  3058. if (sizeTagObj == null)
  3059. {
  3060. Log($"{stepIndex + 1}-{processName}", $"偏移校正轴工序找不到数据提供者Tag:{axisSizeTag}!", WarningEnum.High);
  3061. return stepIndex;
  3062. }
  3063. string[] posePT = sizeTagObj.posePT.Split(',');
  3064. if (posePT.Length < useIndex + AxisIndexList.Count)
  3065. {
  3066. Log($"{stepIndex + 1}-{processName}",
  3067. $"Tag:{axisSizeTag}对应消费索引:{useIndex},Axis数量:{AxisIndexList.Count} 超出postPT:{sizeTagObj.posePT} 范围!", WarningEnum.High);
  3068. return stepIndex;
  3069. }
  3070. double[] TagPPUValue = new double[AxisIndexList.Count];
  3071. for (int i = 0; i < AxisIndexList.Count; i++)
  3072. TagPPUValue[i] = double.Parse(posePT[useIndex + i]);
  3073. string axisTagMsg = $"消费Tag:{axisSizeTag},索引:{useIndex}, 轴:{string.Join(",", AxisIndexList.ToList())},数据:{(TagMoveMode == AxMoveMode.绝对位置 ? "绝对" : "相对")}({string.Join(",", TagPPUValue.ToList())})";
  3074. Log($"{stepIndex + 1}-{processName}", axisTagMsg);
  3075. //界面显示
  3076. OnAutoRuning(new RunEventArgs(liStatocStepIndex, axisTagMsg));
  3077. for (int i = 0; i < AxisIndexList.Count && i < TagPPUValue.Length; i++)
  3078. {
  3079. if (axisDev.CheckDone(AxisIndexList[i], 60) != 0)
  3080. {
  3081. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}到位失败!", WarningEnum.High);
  3082. return stepIndex;
  3083. }
  3084. VelocityCurveParams vel = new VelocityCurveParams(TagAcc, TagDec, TagVelLow, TagVelHigh, MotionST, GetMMtoPlus((AxisName)AxisIndexList[i]));
  3085. int iret = 0;
  3086. if (TagMoveMode == AxMoveMode.绝对位置)
  3087. iret = axisDev.MoveAbsValue(AxisIndexList[i], vel, TagPPUValue[i]);
  3088. else
  3089. iret = axisDev.MoveRelValue(AxisIndexList[i], vel, TagPPUValue[i]);
  3090. if (iret != 0)
  3091. {
  3092. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}运动失败!", WarningEnum.High);
  3093. return stepIndex;
  3094. }
  3095. }
  3096. if (sizeTagObj.ConsumeStepIndex == null) sizeTagObj.ConsumeStepIndex = "";
  3097. sizeTagObj.ConsumeStepIndex += $"{stepIndex + 1}-{useIndex}, ";//消费工序ID
  3098. //多轴同时运行后强制等待各轴完成
  3099. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  3100. if (!WaitAxisDone(AxisIndexList))
  3101. {
  3102. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  3103. return stepIndex;
  3104. }
  3105. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  3106. #endregion
  3107. break;
  3108. case "Light":
  3109. #region
  3110. if (confMgr.SysConfigParams.DisableLight)
  3111. {
  3112. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  3113. //界面显示
  3114. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  3115. break;
  3116. }
  3117. int ChannelIndex = processParam.Value<int>("ChannelIndex"); //通道
  3118. int DigitalValue = processParam.Value<int>("DigitalValue"); //亮度
  3119. int nowDiaitalValue = lightDev.GetLightDigitalValue(ChannelIndex);
  3120. Log($"{stepIndex + 1}-{processName}", $"通道{ChannelIndex}当前值:{nowDiaitalValue},准备更新值:{DigitalValue}...");
  3121. lightDev.SetLightDigitalValue(ChannelIndex, DigitalValue);
  3122. nowDiaitalValue = lightDev.GetLightDigitalValue(ChannelIndex);
  3123. Log($"{stepIndex + 1}-{processName}", $"通道{ChannelIndex}更新后当前值:{nowDiaitalValue}。");
  3124. #endregion
  3125. break;
  3126. case "Scanner_GENTL":
  3127. #region
  3128. if (confMgr.SysConfigParams.DisableBackCam)
  3129. {
  3130. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  3131. //界面显示
  3132. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  3133. break;
  3134. }
  3135. AIEngineLibEnum AIEngineLib = AIEngineLibEnum.缺陷库;
  3136. if (processParam.ContainsKey("AIEngineLib"))
  3137. AIEngineLib = (AIEngineLibEnum)processParam.Value<int>("AIEngineLib");
  3138. float ExposureTime = processParam.Value<float>("ExposureTime"); //曝光
  3139. float Gain = processParam.Value<float>("Gain"); //增益
  3140. float ResultingFrameRate = processParam.Value<float>("ResultingFrameRate"); //帧率
  3141. Log($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  3142. CamDevBack.SetExposure(ExposureTime);
  3143. CamDevBack.SetGain(Gain);
  3144. CamDevBack.SetResultingFrameRate(ResultingFrameRate);
  3145. DateTime dt = DateTime.Now;
  3146. CamDevBack.ClearImageQueue();
  3147. Acquisition acq = CamDevBack.Snap(1, 5000);
  3148. if (acq.GrabStatus != "GrabPass")
  3149. {
  3150. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片失败!", WarningEnum.High);
  3151. return stepIndex;
  3152. }
  3153. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片完成[" + (DateTime.Now - dt).Milliseconds.ToString() + "ms]");
  3154. //显示
  3155. OnAutoRuning(new RunEventArgs(1, acq.Image));
  3156. //----缺陷队列
  3157. if (AIEngineLib == AIEngineLibEnum.缺陷库 || AIEngineLib == AIEngineLibEnum.缺陷与测量库)
  3158. {
  3159. var mat = CamDev.HImageToMat(acq.Image);
  3160. scannerGBmpQueue.Enqueue(new scannerGBmpLoc(mat,
  3161. GetAxisPosValueMM((int)AxisName.Axis1),
  3162. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  3163. Log($"{stepIndex + 1}-{processName}", $"缺陷图像队列数量: {scannerGBmpQueue.Count}");
  3164. }
  3165. if (AIEngineLib == AIEngineLibEnum.测量库 || AIEngineLib == AIEngineLibEnum.缺陷与测量库)
  3166. {
  3167. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  3168. acq.Image.Clone(),
  3169. GetAxisPosValueMM((int)AxisName.Axis1),
  3170. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  3171. Log($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列," +
  3172. $"X:{GetAxisPosValueMM((int)AxisName.Axis1)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  3173. $"数量: {scannerCBmpQueue.Count}");
  3174. }
  3175. #endregion
  3176. break;
  3177. case "Scanner_CC":
  3178. #region
  3179. if (confMgr.SysConfigParams.DisableFrontCam)
  3180. {
  3181. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  3182. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  3183. break;
  3184. }
  3185. if (!WaitAllAxisDone())//因启用轴异步功能,使用前需等待
  3186. {
  3187. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  3188. return stepIndex;
  3189. }
  3190. float ExposureTimeCC = processParam.Value<float>("ExposureTime"); //曝光
  3191. float GainCC = processParam.Value<float>("Gain"); //增益
  3192. float ResultingFrameRateCC = processParam.Value<float>("ResultingFrameRate"); //帧率
  3193. CamDevFront.SetExposure(ExposureTimeCC);
  3194. CamDevFront.SetGain(GainCC);
  3195. CamDevFront.SetResultingFrameRate(ResultingFrameRateCC);
  3196. Log($"{stepIndex + 1}-{processName}", $"相机参数设置完成。");
  3197. bool tAutoFocus = true;
  3198. double tFocusStep = 0.02;
  3199. double tDirStep = 0.04;
  3200. int tWaitTime = 200;
  3201. int tTimeOut = 30000;
  3202. try
  3203. {
  3204. tAutoFocus = processParam.Value<bool>("AutoFocus");
  3205. tFocusStep = processParam.Value<double>("FocusStep");
  3206. tDirStep = processParam.Value<double>("DirStep");
  3207. tWaitTime = processParam.Value<int>("WaitTime");
  3208. tTimeOut = processParam.Value<int>("TimeOut");
  3209. if((tAutoFocus == false)&&(tFocusStep == 0) && (tDirStep == 0) && (tWaitTime == 0) && (tTimeOut == 0))
  3210. {
  3211. tAutoFocus = true;
  3212. tFocusStep = 0.02;
  3213. tDirStep = 0.04;
  3214. tWaitTime = 200;
  3215. tTimeOut = 30000;
  3216. Log($"{stepIndex + 1}-{processName}", $"无参数,使用默认参数!");
  3217. }
  3218. }
  3219. catch
  3220. {
  3221. tAutoFocus = true;
  3222. tFocusStep = 0.02;
  3223. tDirStep = 0.04;
  3224. tWaitTime = 200;
  3225. tTimeOut = 30000;
  3226. Log($"{stepIndex + 1}-{processName}", $"错误参数,使用默认参数!");
  3227. }
  3228. if ((tAutoFocus)&&(ExposureTimeCC > 0))
  3229. {
  3230. Log($"{stepIndex + 1}-{processName}", $"开始自动聚焦...");
  3231. if (!AutoFocus(tFocusStep, tDirStep, tWaitTime, tTimeOut))
  3232. {
  3233. Log($"{stepIndex + 1}-{processName}", $"自动聚焦失败!", WarningEnum.High);
  3234. return stepIndex;
  3235. }
  3236. Log($"{stepIndex + 1}-{processName}", $"自动聚焦完成");
  3237. }
  3238. Log($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  3239. DateTime dt0 = DateTime.Now;
  3240. CamDevFront.ClearImageQueue();
  3241. Acquisition acq0 = CamDevFront.Snap(1, 5000);
  3242. if (acq0.GrabStatus != "GrabPass")
  3243. {
  3244. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片失败!", WarningEnum.High);
  3245. return stepIndex;
  3246. }
  3247. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片完成[" + (DateTime.Now - dt0).Milliseconds.ToString() + "ms]");
  3248. //显示
  3249. OnAutoRuning(new RunEventArgs(0, acq0.Image));
  3250. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  3251. acq0.Image.Clone(),
  3252. GetAxisPosValueMM((int)AxisName.Axis0),
  3253. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  3254. Log($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列," +
  3255. $"X:{GetAxisPosValueMM((int)AxisName.Axis0)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  3256. $"数量: {scannerCBmpQueue.Count}");
  3257. #endregion
  3258. break;
  3259. case "SmallAxis":
  3260. #region
  3261. if (confMgr.SysConfigParams.DisableLensMotor)
  3262. {
  3263. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  3264. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!"));
  3265. break;
  3266. }
  3267. int CmdPos = processParam.Value<int>("CmdPos"); //命令脉冲
  3268. Log($"{stepIndex + 1}-{processName}", $"开始由起始位置{lensMotorDev.GetFeedbackPos(0)}运动到{CmdPos}...");
  3269. lensMotorDev.MoveAbsPulse(0, new VelocityCurveParams(), CmdPos);
  3270. lensMotorDev.CheckDone(0, 10000);
  3271. Log($"{stepIndex + 1}-{processName}", $"运动完成,当前位置:{lensMotorDev.GetFeedbackPos(0)}");
  3272. #endregion
  3273. break;
  3274. case "Size":
  3275. #region
  3276. asynRun = processParam.Value<bool>("AsynRun");//异步
  3277. limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
  3278. lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
  3279. int sizeIndex = processParam.Value<int>("Index");
  3280. string sizeTag = processParam.ContainsKey("SizeTag") ? processParam.Value<string>("SizeTag") : "";
  3281. //2023-10-27
  3282. bool useMap = false;
  3283. List<double> getPosList = new List<double>();
  3284. try
  3285. {
  3286. //是否有新的使用点位
  3287. useMap = processParam.Value<bool>("UseMapPoints");
  3288. if (useMap)
  3289. {
  3290. var list = model.GetPointList.Split(',');
  3291. List<double> dList = new List<double>();
  3292. if (list.Length < 28)
  3293. {
  3294. for (int i = 0; i < 28; i++)
  3295. dList.Add(0);
  3296. }
  3297. else
  3298. {
  3299. for (int i = 0; i < list.Length; i++)
  3300. dList.Add(double.Parse(list[i]));
  3301. }
  3302. getPosList = dList;
  3303. }
  3304. else
  3305. {
  3306. for (int i = 0; i < 28; i++)
  3307. getPosList.Add(0);
  3308. }
  3309. //getPosList = processParam.Value<JArray>("GetPointList").ToObject<List<double>>();
  3310. }
  3311. catch
  3312. {
  3313. for (int i = 0; i < 28; i++)
  3314. getPosList.Add(0);
  3315. }
  3316. double[] getPosArray = getPosList.ToArray();
  3317. if (scannerCBmpQueue.Count < 1)
  3318. {
  3319. Log($"{stepIndex + 1}-{processName}", $"尺寸检测异常,无源图像!!", WarningEnum.Low);
  3320. return stepIndex;
  3321. }
  3322. var bmpCBmpQueue = scannerCBmpQueue.Dequeue();
  3323. Log($"{stepIndex + 1}-{processName}", $"开始尺寸检测,index:{sizeIndex},posX:{bmpCBmpQueue.PosX},posY:{bmpCBmpQueue.PosY},图像队列数量: {scannerCBmpQueue.Count}...");
  3324. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  3325. Log($"{stepIndex + 1}-{processName}", $"尺寸检测,index:{sizeIndex},{model.AttachmentList.Count}|{(attachmentFile == null ? "null" : attachmentFile.NameTimestamp + attachmentFile.ExtendName)}");
  3326. if (attachmentFile != null)
  3327. {
  3328. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  3329. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName))
  3330. gbxBmpPath = "";
  3331. }
  3332. if ((sizeIndex == 333 || sizeIndex == 777) && gbxBmpPath == "")
  3333. Log($"{stepIndex + 1}-{processName}", $"尺寸检测,index:{sizeIndex},图纸不存在!", WarningEnum.Low);
  3334. //2023-10-27
  3335. if (useMap && (sizeIndex == 3333) && (getPosArray != null) && (getPosArray.Count() == 28) && (getPosArray[0] != 0))
  3336. Log($"{stepIndex + 1}-{processName}", $"开始图纸读点,index:{sizeIndex},PT1:{getPosArray[0]},PT2:{getPosArray[2]},PT3:{getPosArray[4]},PT4:{getPosArray[6]},PT5:{getPosArray[8]}," +
  3337. $"线宽1:[{getPosArray[10]},{getPosArray[11]}],线宽2:[{getPosArray[12]},{getPosArray[13]}],线宽3:[{getPosArray[14]},{getPosArray[15]}]," +
  3338. $"线宽4:[{getPosArray[16]},{getPosArray[17]}],线宽5:[{getPosArray[18]},{getPosArray[19]}],线宽6:[{getPosArray[20]},{getPosArray[21]}]," +
  3339. $"线宽7:[{getPosArray[22]},{getPosArray[23]}],线宽8:[{getPosArray[24]},{getPosArray[25]}],线宽9:[{getPosArray[26]},{getPosArray[27]}]");
  3340. //需要偏移校正,index=0时不能异步 //10,20,30... 
  3341. endEvent = new AutoResetEvent(false);
  3342. SizeLib.add(new SizeTask()
  3343. {
  3344. stepIndex = stepIndex,
  3345. processName = processName,
  3346. sizeTag = sizeTag,
  3347. engineName = processParam.Value<string>("EngineName"),
  3348. Himage = bmpCBmpQueue.Himage.Clone(),//bmp/file_path二选一,优先bmp
  3349. file_path = bmpCBmpQueue.Path,
  3350. drawingPagePath = gbxBmpPath,
  3351. posX = bmpCBmpQueue.PosX,
  3352. posY = bmpCBmpQueue.PosY,
  3353. //2023-10-27
  3354. PTandLinePos = getPosArray,
  3355. index = sizeIndex,// scannerCBmpIndex++,
  3356. ContoursAffineTrans1_Out = this.contoursAffineTrans1_Out,//只有777时才使用最近333输出的结果
  3357. finishEvent = (res) =>
  3358. {
  3359. try
  3360. {
  3361. //比对
  3362. if (res.index == 777)//比对
  3363. {
  3364. if (res.isSucceed)
  3365. {
  3366. //界面显示
  3367. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},图像比对:{(res.CompResult ? "通过" : "未通过")} "));
  3368. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对,index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},结果:{(res.CompResult ? "通过" : "未通过")}");
  3369. //
  3370. if (order.CompareResult < 2)
  3371. order.CompareResult = res.CompResult ? 1 : 2;
  3372. if (!res.CompResult)
  3373. {
  3374. //不合格
  3375. order.Qualified = false;
  3376. }
  3377. //更新比对看板 对比置零3
  3378. if (!res.CompResult)
  3379. SizeNGCnt++;
  3380. if (SizeNGCnt > 0)
  3381. OnAutoRuning(new RunEventArgs(3, false, SizeNGCnt));
  3382. else
  3383. OnAutoRuning(new RunEventArgs(3, true, SizeNGCnt));
  3384. if (!res.CompResult)
  3385. {
  3386. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对,未通过结果:{JsonConvert.SerializeObject(res.defectInfor2RestorationDesk)}");
  3387. //转为图纸上坐标位置
  3388. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  3389. {
  3390. //AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"转换到图纸后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
  3391. if (order.DefectInfoList == null)
  3392. order.DefectInfoList = new List<DefectInfo>();
  3393. foreach (var item in res.defectInfor2RestorationDeskPage)
  3394. order.DefectInfoList.Add(new DefectInfo()
  3395. {
  3396. Type = 1,
  3397. Code = item[3],
  3398. X = double.Parse(item[1]),
  3399. Y = double.Parse(item[2]),
  3400. ZXD = double.Parse(item[4]),
  3401. Index = int.Parse(item[0]),
  3402. ModifyUserCode = userMgr.LoginUser.Code,
  3403. CreateUserCode = userMgr.LoginUser.Code,
  3404. });
  3405. }
  3406. //比对失败的图片 -- 用于修复台调用
  3407. Bitmap bmpCompareFailZoomImage = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.Zoom_Image_mat);
  3408. lstCompareFailZoomImage.Add(bmpCompareFailZoomImage);
  3409. if (confMgr.SysConfigParams.SizeRepairImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeRepairImag.SavePath))
  3410. {
  3411. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeRepairImag.SavePath,
  3412. new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3413. //path += $"Size_SN{order.SN}_I{res.index}_X{res.Defects_X}_Y{res.Defects_Y}_C0_{ model.StepInfo.Name}";
  3414. path += $"Size_SN{order.SN}_I{compBmpIndex}_X{res.posX}_Y{res.posY}_C0_{model.StepInfo.Name}";
  3415. lock (ImageSaveObj)
  3416. {
  3417. bmpCompareFailZoomImage.Save(path + ".bmp", ImageFormat.Bmp);
  3418. if (res.defectInfor2RestorationDesk != null && res.defectInfor2RestorationDesk.Count > 0)
  3419. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
  3420. }
  3421. }
  3422. //保存不良原图
  3423. if (confMgr.SysConfigParams.SizeNGImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeNGImag.SavePath))
  3424. {
  3425. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeNGImag.SavePath,
  3426. new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3427. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}.bmp";
  3428. Log($"{res.stepIndex + 1}-{processName}", $"未通过图片保存:{path}");
  3429. if (res.Himage != null)
  3430. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  3431. else
  3432. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  3433. }
  3434. }
  3435. }
  3436. else
  3437. {
  3438. order.CompareResult = 2;
  3439. order.Qualified = false;
  3440. SizeNGCnt++;
  3441. OnAutoRuning(new RunEventArgs(3, false, SizeNGCnt));
  3442. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index},图像比对失败!"));
  3443. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对失败,index:{res.index}-{compBmpIndex}.", WarningEnum.Low);
  3444. }
  3445. compBmpIndex++;
  3446. }
  3447. //MARK
  3448. else if (res.index == 111 || res.index == 222 || res.index == 333 || res.index == 444)
  3449. {
  3450. Log($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index},结果记录...");
  3451. if (res.index == 333) this.contoursAffineTrans1_Out = res.ContoursAffineTrans1_Out;//不管成功失败都替换
  3452. if (res.isSucceed)
  3453. {
  3454. Thread.Sleep(100);
  3455. Log($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index}; 当前值:{string.Join(",", res.MarkPointList)}");
  3456. JArray markDatas;
  3457. if (string.IsNullOrWhiteSpace(order.MarkData))
  3458. markDatas = new JArray() { 0, 0, 0, 0, 0, 0, 0, 0 };
  3459. else
  3460. markDatas = JArray.Parse(order.MarkData);
  3461. for (int i = 0; i < res.MarkPointList.Count(); i++)
  3462. if (res.MarkPointList[i] != 0)
  3463. markDatas[i] = res.MarkPointList[i];
  3464. order.MarkData = markDatas.ToString();
  3465. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index},Mark点:{order.MarkData} "));
  3466. Log($"{res.stepIndex + 1}-{processName}", $"Mark点 Index={res.index};合并后:{order.MarkData}");
  3467. }
  3468. else
  3469. {
  3470. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index},Mark点计算失败!"));
  3471. Log($"{res.stepIndex + 1}-{processName}", $"Mark点计算失败,index:{res.index}.", confMgr.SysConfigParams.OpenMarkErrorStop ? WarningEnum.High : WarningEnum.Normal);
  3472. }
  3473. //保存
  3474. if (confMgr.SysConfigParams.SizeBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeBigImag.SavePath))
  3475. {
  3476. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3477. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}.bmp";
  3478. if (res.Himage != null)
  3479. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  3480. else
  3481. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  3482. }
  3483. }
  3484. else
  3485. {
  3486. int roundIndex = res.index % 10;
  3487. if (res.isSucceed)
  3488. {
  3489. string tagOutData = "";
  3490. if (res.index == 3333 && !string.IsNullOrWhiteSpace(res.sizeTag))
  3491. {
  3492. tagOutData = $"Tag:{res.sizeTag},posePT:[{string.Join(",", res.posePT)}]";
  3493. if (res.posePT.Length < 2 || res.posePT.Length % 2 != 0)
  3494. {
  3495. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测输出Tag对应posePT非法: {tagOutData}", WarningEnum.High);
  3496. return;
  3497. }
  3498. //2023-10-27
  3499. Log($"{res.stepIndex + 1}-{res.processName}", $"Tag对应posePT: {tagOutData}", WarningEnum.Normal);
  3500. if (order.SizeTagDataList == null)
  3501. order.SizeTagDataList = new List<SizeTagData>();
  3502. order.SizeTagDataList.Add(new SizeTagData()
  3503. {
  3504. SizeTag = res.sizeTag,
  3505. CreateStepIndex = res.stepIndex + 1,
  3506. posePT = string.Join(",", res.posePT)// 回转 Array.ConvertAll(sNums , double.Parse);
  3507. });
  3508. }
  3509. OnAutoRuning(new RunEventArgs(liStatocStepIndex,
  3510. $"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}"));
  3511. 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} ");
  3512. //测量
  3513. //------TEST
  3514. if (res.index > 20 && res.index < 30)
  3515. {
  3516. //PT测量
  3517. lock (lstPT)
  3518. {
  3519. lstPT.Add(Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4));
  3520. Log($"PT值", $"PT{lstPT.Count}:{Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4)}");
  3521. OnAutoRuning(new RunEventArgs(22, lstPT, model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue));
  3522. double PtValue = Math.Round(lstPT.Average(), 4);
  3523. if (order != null)
  3524. order.PTValue = PtValue;
  3525. if (order != null)
  3526. {
  3527. if (lstPT.Count == 1)
  3528. order.PT1 = Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4);
  3529. else if (lstPT.Count == 2)
  3530. order.PT2 = Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4);
  3531. else if (lstPT.Count == 3)
  3532. order.PT3 = Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4);
  3533. else if (lstPT.Count == 4)
  3534. order.PT5 = Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4);
  3535. else if (lstPT.Count == 5)
  3536. order.PT6 = Math.Round(res.PT1 + confMgr.SysConfigParams.Pt_offset, 4);
  3537. }
  3538. double PtUpper = model.PTBaseValue + model.PTUpFloatValue;
  3539. double PtLower = model.PTBaseValue - model.PTDownFloatValue;
  3540. if (PtUpper + PtLower > 0 && (PtValue > PtUpper || PtValue < PtLower))
  3541. order.Qualified = false;
  3542. }
  3543. }
  3544. //------
  3545. if (roundIndex > 0)//1-9测量
  3546. {
  3547. if (res.index < 10)
  3548. {
  3549. //线宽测量
  3550. lock (lstLineWidth)
  3551. {
  3552. double lineWidthValue = res.Shanxian > 0 ? Math.Round(res.Shanxian + confMgr.SysConfigParams.Line_offset, 2) : 0;
  3553. lstLineWidth.Add(lineWidthValue);
  3554. Log($"线宽值", $"线宽{lstLineWidth.Count}:{lineWidthValue}");
  3555. OnAutoRuning(new RunEventArgs(23, lstLineWidth, model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue));
  3556. double LwValue = Math.Round(lstLineWidth.Average(), 2);
  3557. if (order != null)
  3558. order.LineWidthValue = LwValue;
  3559. if (order != null)
  3560. {
  3561. if (lstLineWidth.Count == 1)
  3562. order.LineWidth1 = lineWidthValue;
  3563. else if (lstLineWidth.Count == 2)
  3564. order.LineWidth2 = lineWidthValue;
  3565. else if (lstLineWidth.Count == 3)
  3566. order.LineWidth3 = lineWidthValue;
  3567. else if (lstLineWidth.Count == 4)
  3568. order.LineWidth4 = lineWidthValue;
  3569. else if (lstLineWidth.Count == 5)
  3570. order.LineWidth5 = lineWidthValue;
  3571. else if (lstLineWidth.Count == 6)
  3572. order.LineWidth6 = lineWidthValue;
  3573. else if (lstLineWidth.Count == 7)
  3574. order.LineWidth7 = lineWidthValue;
  3575. else if (lstLineWidth.Count == 8)
  3576. order.LineWidth8 = lineWidthValue;
  3577. else if (lstLineWidth.Count == 9)
  3578. order.LineWidth9 = lineWidthValue;
  3579. }
  3580. double LwUpper = model.LineWidthBaseValue + model.LineWidthUpFloatValue;
  3581. double LwLower = model.LineWidthBaseValue - model.LineWidthDownFloatValue;
  3582. if (LwUpper + LwLower > 0 && (LwValue > LwUpper || LwValue < LwLower))
  3583. order.Qualified = false;
  3584. }
  3585. }
  3586. }
  3587. //校正偏移 10,20,30...:偏移
  3588. else
  3589. {
  3590. AxMoveMode axSizeMode = AxMoveMode.绝对位置;
  3591. double xPos = 0;
  3592. double yPos = 0;
  3593. //绝对偏移
  3594. if (res.offsetX != 0 || res.offsetY != 0)
  3595. {
  3596. xPos += res.offsetX;
  3597. yPos += res.offsetY;
  3598. Log($"{res.stepIndex + 1}-{res.processName}", $"offsetX/Y绝对校正, 0轴:{xPos}mm, 2轴:{yPos}mm");
  3599. }
  3600. else if (res.Circle_Xmm != 0 || res.Circle_Ymm != 0)//相对偏移校正
  3601. {
  3602. axSizeMode = AxMoveMode.相对位置;
  3603. Log($"{res.stepIndex + 1}-{res.processName}", $"原点相对校正, 0轴:{res.Circle_Xmm}mm, 2轴:{res.Circle_Ymm}mm");
  3604. if (res.Circle_Xmm != 0) xPos = res.Circle_Xmm;
  3605. if (res.Circle_Ymm != 0) yPos = res.Circle_Ymm;
  3606. }
  3607. //当前工序直接移动
  3608. if (xPos != 0 || yPos != 0)
  3609. {
  3610. ;
  3611. }
  3612. }
  3613. }
  3614. //失败
  3615. else
  3616. {
  3617. if((res.index == 3333)||(res.index == 1111)||(res.index == 2222)||(res.index == 4444))
  3618. {
  3619. Log($"{res.stepIndex + 1}-{processName}", $"Mark点计算失败,index:{res.index}.", confMgr.SysConfigParams.OpenMarkErrorStop ? WarningEnum.High : WarningEnum.Normal);
  3620. }
  3621. //------TEST
  3622. if (res.index > 20 && res.index < 30)
  3623. {
  3624. //PT测量
  3625. lock (lstPT)
  3626. {
  3627. lstPT.Add(0);
  3628. Log($"PT值", $"PT{lstPT.Count}:0");
  3629. OnAutoRuning(new RunEventArgs(22, lstPT, model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue));
  3630. double PtValue = Math.Round(lstPT.Average(), 4);
  3631. if (order != null)
  3632. order.PTValue = PtValue;
  3633. if (order != null)
  3634. {
  3635. if (lstPT.Count == 1)
  3636. order.PT1 = 0;
  3637. else if (lstPT.Count == 2)
  3638. order.PT2 = 0;
  3639. else if (lstPT.Count == 3)
  3640. order.PT3 = 0;
  3641. else if (lstPT.Count == 4)
  3642. order.PT5 = 0;
  3643. else if (lstPT.Count == 5)
  3644. order.PT6 = 0;
  3645. }
  3646. double PtUpper = model.PTBaseValue + model.PTUpFloatValue;
  3647. double PtLower = model.PTBaseValue - model.PTDownFloatValue;
  3648. if (PtUpper + PtLower > 0 && (PtValue > PtUpper || PtValue < PtLower))
  3649. order.Qualified = false;
  3650. }
  3651. }
  3652. //------
  3653. if (roundIndex > 0)
  3654. {
  3655. if (res.index < 10)
  3656. {
  3657. //线宽测量
  3658. lock (lstLineWidth)
  3659. {
  3660. lstLineWidth.Add(0);
  3661. Log($"线宽值", $"线宽{lstLineWidth.Count}:0");
  3662. OnAutoRuning(new RunEventArgs(23, lstLineWidth, model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue));
  3663. double LwValue = Math.Round(lstLineWidth.Average(), 2);
  3664. if (order != null)
  3665. order.LineWidthValue = LwValue;
  3666. if (order != null)
  3667. {
  3668. if (lstLineWidth.Count == 1)
  3669. order.LineWidth1 = 0;
  3670. else if (lstLineWidth.Count == 2)
  3671. order.LineWidth2 = 0;
  3672. else if (lstLineWidth.Count == 3)
  3673. order.LineWidth3 = 0;
  3674. else if (lstLineWidth.Count == 4)
  3675. order.LineWidth4 = 0;
  3676. else if (lstLineWidth.Count == 5)
  3677. order.LineWidth5 = 0;
  3678. else if (lstLineWidth.Count == 6)
  3679. order.LineWidth6 = 0;
  3680. else if (lstLineWidth.Count == 7)
  3681. order.LineWidth7 = 0;
  3682. else if (lstLineWidth.Count == 8)
  3683. order.LineWidth8 = 0;
  3684. else if (lstLineWidth.Count == 9)
  3685. order.LineWidth9 = 0;
  3686. }
  3687. double LwUpper = model.LineWidthBaseValue + model.LineWidthUpFloatValue;
  3688. double LwLower = model.LineWidthBaseValue - model.LineWidthDownFloatValue;
  3689. if (LwUpper + LwLower > 0 && (LwValue > LwUpper || LwValue < LwLower))
  3690. order.Qualified = false;
  3691. }
  3692. }
  3693. }
  3694. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"失败:{res.resultInfo}"));
  3695. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测失败index:{res.index}:{res.resultInfo}");
  3696. }
  3697. //保存
  3698. if (confMgr.SysConfigParams.SizeBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeBigImag.SavePath))
  3699. {
  3700. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3701. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}.bmp";
  3702. if (res.Himage != null)
  3703. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  3704. else
  3705. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  3706. }
  3707. }
  3708. }
  3709. catch (Exception ex)
  3710. {
  3711. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测回调处理异常 index:{res.index},ex={ex.Message}");
  3712. }
  3713. endEvent.Set();//roundIndex=0成功或失败线程返回
  3714. //---
  3715. if (res.Himage != null)
  3716. {
  3717. res.Himage.Dispose();
  3718. res.Himage = null;
  3719. }
  3720. else
  3721. {
  3722. API.DeleteFile(res.file_path);
  3723. }
  3724. }
  3725. });
  3726. //需等上面异步回调中的相对偏移校正完成再继续
  3727. if (!asynRun || sizeIndex % 10 == 0)
  3728. {
  3729. if (!endEvent.WaitOne(60000))
  3730. Log($"{stepIndex + 1}-{processName}", $"{sizeIndex}等待超时,忽略继续!", WarningEnum.Low);
  3731. }
  3732. #endregion
  3733. break;
  3734. case "Defect":
  3735. #region
  3736. limitThresholdVal = processParam.Value<double>("LimitThresholdVal");
  3737. lowerThresholdVal = processParam.Value<double>("LowerThresholdVal");
  3738. if (scannerGBmpQueue.Count < 1)
  3739. {
  3740. Log($"{stepIndex + 1}-{processName}", $"缺陷检测异常,无源图像!!", WarningEnum.Low);
  3741. return stepIndex;
  3742. }
  3743. var bmpLoc = scannerGBmpQueue.Dequeue();
  3744. Log($"{stepIndex + 1}-{processName}", $"开始缺陷检测,源图索引:{defectBmpNum},图像队列数量: {scannerGBmpQueue.Count}...");
  3745. string[] aarCut_size = processParam.Value<string>("CutSize").Split(',');
  3746. string[] aarResize = processParam.Value<string>("Resize").Split(',');
  3747. //图纸
  3748. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  3749. if (attachmentFile != null)
  3750. {
  3751. gbxBmpPath = ConfMgr.Instance.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  3752. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName)) gbxBmpPath = "";
  3753. }
  3754. Log($"{stepIndex + 1}-{processName}", $"图纸路径:{gbxBmpPath}");
  3755. defectLib.add(new DefectTask()
  3756. {
  3757. stepIndex = stepIndex,
  3758. processName = processName,
  3759. drawingPagePath = gbxBmpPath,
  3760. //index = defectBmpNum++,
  3761. index = defectBmpNum,
  3762. bmp = bmpLoc.bmp.Clone(),
  3763. Xmm = bmpLoc.Xmm,
  3764. Ymm = bmpLoc.Ymm,
  3765. cut_size = new System.Drawing.Size(Convert.ToInt32(aarCut_size[0]), Convert.ToInt32(aarCut_size[1])),
  3766. resize = new System.Drawing.Size(Convert.ToInt32(aarResize[0]), Convert.ToInt32(aarResize[1])),
  3767. thresholds = processParam.Value<float>("Thresholds"),
  3768. thresholdsClass = processParam.Value<string>("ThresholdsClass"),
  3769. recAreaThreshold = getProductAreaThreshol(model), //qxName,面积; qxName,面积; qxName,面积;
  3770. finishEvent = (res) =>
  3771. {
  3772. if (res.isSucceed)
  3773. {
  3774. //界面显示
  3775. OnAutoRuning(new RunEventArgs(liStatocStepIndex,
  3776. $"源图索引:{res.index},缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}"));
  3777. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测完成(源图索引:{res.index}),缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}");
  3778. string path;
  3779. if (res.defectCount > 0)
  3780. {
  3781. //UI显示小图 (含统计缺陷类型数量)
  3782. AllDefectCount += res.informationList.Count;
  3783. showDefectSmallBmps(res.bmps_tag, res.bmps_cut, res.Xmm, res.Ymm, res.informationList);
  3784. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  3785. {
  3786. Log($"{res.stepIndex + 1}-{res.processName}", $"转换后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
  3787. if (order.DefectInfoList == null)
  3788. order.DefectInfoList = new List<DefectInfo>();
  3789. foreach (var item in res.defectInfor2RestorationDeskPage)
  3790. order.DefectInfoList.Add(new DefectInfo()
  3791. {
  3792. Type = 0,
  3793. Code = item[3],
  3794. X = double.Parse(item[1]),
  3795. Y = double.Parse(item[2]),
  3796. ZXD = double.Parse(item[4]),
  3797. Index = int.Parse(item[0]),
  3798. Area = item.Count > 5 ? double.Parse(item[5]) : 0,
  3799. ModifyUserCode = UserMgr.LoginUser.Code,
  3800. CreateUserCode = UserMgr.LoginUser.Code,
  3801. });
  3802. }
  3803. //保存原始大图
  3804. if (confMgr.SysConfigParams.DefectBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectBigImag.SavePath))
  3805. {
  3806. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3807. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{model.StepInfo.Name}";
  3808. lock (ImageSaveObj)
  3809. {
  3810. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
  3811. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.informationList));
  3812. }
  3813. }
  3814. //保存小图
  3815. if (confMgr.SysConfigParams.DefectSmallImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectSmallImag.SavePath))
  3816. {
  3817. //2024-03-07 图片index计算
  3818. List<string> indexList = new List<string>();
  3819. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  3820. foreach (var item in res.defectInfor2RestorationDeskPage)
  3821. {
  3822. if (indexList.Count == 0)
  3823. indexList.Add(item[0]);
  3824. else
  3825. {
  3826. if (!indexList.Contains(item[0]))
  3827. indexList.Add(item[0]);
  3828. }
  3829. }
  3830. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectSmallImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3831. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_{model.StepInfo.Name}";
  3832. if (res.bmps_tag.Count() != indexList.Count)
  3833. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷图片张数和index对不上:{res.bmps_tag.Count()} - {indexList.Count}", WarningEnum.Low);
  3834. for (int i = 0; i < res.bmps_tag.Count(); i++)
  3835. {
  3836. lock (ImageSaveObj)
  3837. {
  3838. if (res.bmps_tag.Count() != indexList.Count)
  3839. res.bmps_tag[i].Save(path + $"_i{i}_{i}.bmp", ImageFormat.Bmp);
  3840. else
  3841. res.bmps_tag[i].Save(path + $"_i{i}_{indexList[i]}.bmp", ImageFormat.Bmp);
  3842. }
  3843. //res.bmps_tag[i].Save(path + $"_i{i}.bmp", ImageFormat.Bmp);
  3844. //res.bmps_tag[i].Save(path + $"{indexList[i]}.bmp", ImageFormat.Bmp);
  3845. }
  3846. }
  3847. //保存压缩大图 -- 用于修复台调用
  3848. if (confMgr.SysConfigParams.DefectRepairImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectRepairImag.SavePath))
  3849. {
  3850. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectRepairImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3851. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{model.StepInfo.Name}";
  3852. lock (ImageSaveObj)
  3853. {
  3854. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmpCompress).Save(path + ".bmp", ImageFormat.Bmp);
  3855. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
  3856. }
  3857. }
  3858. }
  3859. else//没有缺陷
  3860. {
  3861. if (confMgr.SysConfigParams.SaveAllImg && confMgr.SysConfigParams.DefectBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectBigImag.SavePath))
  3862. {
  3863. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  3864. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{model.StepInfo.Name}";
  3865. lock (ImageSaveObj)
  3866. {
  3867. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
  3868. }
  3869. }
  3870. }
  3871. }
  3872. else
  3873. {
  3874. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"失败:{res.resultInfo}"));
  3875. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测失败:{res.resultInfo}");
  3876. //暂停 这里不能暂停,stepIndex和scannerBmpQueue队列也不对了
  3877. }
  3878. defectBmpNumResult++;
  3879. foreach (var item in res.bmps_cut)
  3880. item.Dispose();
  3881. res.bmp.Dispose();
  3882. res.bmp = null;
  3883. res.bmps_tag = null;
  3884. if (res.bmpCompress != null)
  3885. {
  3886. res.bmpCompress.Dispose();
  3887. res.bmpCompress = null;
  3888. }
  3889. System.GC.Collect();
  3890. }
  3891. });
  3892. defectBmpNum++;
  3893. #endregion
  3894. break;
  3895. case "For":
  3896. #region
  3897. long UniqueId = processParam.Value<long>("UniqueId");
  3898. int GotoStepIndex = processParam.Value<int>("GotoStepIndex");//1-n
  3899. int LimitNum = processParam.Value<int>("LimitNum");//1-n
  3900. bool Reset = processParam.Value<bool>("Reset");
  3901. if (GotoStepIndex - 1 == stepIndex)
  3902. {
  3903. Log($"{stepIndex + 1}-{processName}", $"For死循环!!!", WarningEnum.High);
  3904. return stepIndex;
  3905. }
  3906. if (!forLib.dicData.ContainsKey(UniqueId))
  3907. forLib.dicData.Add(UniqueId, 0);
  3908. //
  3909. int Num = forLib.dicData[UniqueId];
  3910. Num++;
  3911. if (Num <= LimitNum)
  3912. {
  3913. if (Num == LimitNum)
  3914. {
  3915. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num}/{LimitNum}]次,循环完成"));
  3916. Log($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次,循环完成。");
  3917. }
  3918. else
  3919. {
  3920. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num}/{LimitNum}]次"));
  3921. Log($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次跳转到步骤[{GotoStepIndex}]...");
  3922. stepIndex = GotoStepIndex - 2;
  3923. }
  3924. forLib.dicData[UniqueId] = Num;
  3925. }
  3926. else
  3927. {
  3928. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"已失效不执行"));
  3929. Log($"{stepIndex + 1}-{processName}", $"本循环已失效不执行!");
  3930. }
  3931. //达到limit重置0
  3932. if (forLib.dicData[UniqueId] >= LimitNum && Reset)
  3933. {
  3934. forLib.dicData[UniqueId] = 0;
  3935. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[0/{LimitNum}]次"));
  3936. Log($"{stepIndex + 1}-{processName}", $"计数器已重置。");
  3937. }
  3938. #endregion
  3939. break;
  3940. case "If":
  3941. #region
  3942. long UniqueId_if = processParam.Value<long>("UniqueId");
  3943. int GotoStepIndex_if = processParam.Value<int>("GotoStepIndex");//1-n
  3944. int LimitNum_if = processParam.Value<int>("LimitNum");//1-n
  3945. bool Reset_if = processParam.Value<bool>("Reset");
  3946. if (GotoStepIndex_if - 1 == stepIndex)
  3947. {
  3948. Log($"{stepIndex + 1}-{processName}", $"If死循环,不可自我跳转!!!", WarningEnum.High);
  3949. return stepIndex;
  3950. }
  3951. //
  3952. if (!ifLib.dicData.ContainsKey(UniqueId_if))
  3953. ifLib.dicData.Add(UniqueId_if, 0);
  3954. //
  3955. int Num_if = ifLib.dicData[UniqueId_if];
  3956. Num_if++;
  3957. if (Num_if <= LimitNum_if)
  3958. {
  3959. if (Num_if == LimitNum_if)
  3960. {
  3961. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num_if}/{LimitNum_if}]次,跳转至[{GotoStepIndex_if}]"));
  3962. Log($"{stepIndex + 1}-{processName}", $"计数器[{Num_if}/{LimitNum_if}],跳转至步骤[{GotoStepIndex_if}]...");
  3963. stepIndex = GotoStepIndex_if - 2;
  3964. }
  3965. else
  3966. {
  3967. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num_if}/{LimitNum_if}]次,不跳转"));
  3968. Log($"{stepIndex + 1}-{processName}", $"计数器[{Num_if}/{LimitNum_if}],不跳转。");
  3969. }
  3970. //
  3971. ifLib.dicData[UniqueId_if] = Num_if;
  3972. }
  3973. else
  3974. {
  3975. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"已失效不执行"));
  3976. Log($"{stepIndex + 1}-{processName}", $"本IF已失效不执行。");
  3977. }
  3978. //达到limit重置0
  3979. if (ifLib.dicData[UniqueId_if] >= LimitNum_if && Reset_if)
  3980. {
  3981. ifLib.dicData[UniqueId_if] = 0;
  3982. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[0/{LimitNum_if}]次"));
  3983. Log($"{stepIndex + 1}-{processName}", $"计数器已重置。");
  3984. }
  3985. #endregion
  3986. break;
  3987. default:
  3988. Log($"{stepIndex + 1}-{processName}", $"未知工序:{processInfo.ProcessCode}", WarningEnum.High);
  3989. return stepIndex;
  3990. }
  3991. if (sleepLater > 0) Thread.Sleep((int)sleepLater);
  3992. #endregion
  3993. }
  3994. else
  3995. {
  3996. #region 新流程/快速流程
  3997. #region 参数
  3998. int AxisX1 = (int)AxisName.Axis0;
  3999. int AxisX2 = (int)AxisName.Axis1;
  4000. int AxisY = (int)AxisName.Axis2;
  4001. int AxisZ = (int)AxisName.Axis3;
  4002. TestCnt = 0;
  4003. int liStatocStepIndex = stepIndex;
  4004. int DelayTime = 0;
  4005. int DataCnt = 0;
  4006. double OffsetValue = 0;
  4007. DataProcess dataProcess = DataProcess.均值;
  4008. DataJudgment judgmentData = DataJudgment.均值;
  4009. List<PointF> Points = new List<PointF>();
  4010. double VelLow = 0;
  4011. double VelHigh = 0;
  4012. double Acc = 0;
  4013. double Dec = 0;
  4014. int WaitTime = 0;
  4015. double upLimit = 0;
  4016. double loLimit = 0;
  4017. List<double> tempDataList = new List<double>();
  4018. Models.Attachment attachmentFile;
  4019. string gbxBmpPath = "";
  4020. List<string> testLabels = new List<string>();
  4021. Type tp = typeof(PointTestType);
  4022. FieldInfo[] fieldInfos = tp.GetFields();
  4023. foreach (var item in fieldInfos)
  4024. {
  4025. //不是枚举字段不处理
  4026. if (item.FieldType.IsEnum)
  4027. {
  4028. //名称可以直接获取
  4029. testLabels.Add(item.Name);
  4030. }
  4031. }
  4032. #endregion
  4033. switch (processInfo.ProcessCode)
  4034. {
  4035. case "Tension":
  4036. #region 张力测试
  4037. if (confMgr.SysConfigParams.DisableTensor)
  4038. {
  4039. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4040. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4041. break;
  4042. }
  4043. if (!SizeEnable)
  4044. {
  4045. Log($"{stepIndex + 1}-{processName}", $"尺寸检测功能禁用,忽略此步骤!");
  4046. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"尺寸检测功能禁用,忽略此步骤!", 0, false));
  4047. break;
  4048. }
  4049. TestCnt = processParam.Value<int>("TestCnt");
  4050. dataProcess = (DataProcess)processParam.Value<int>("ProcessData");
  4051. DelayTime = processParam.Value<int>("DelayTime");
  4052. DataCnt = processParam.Value<int>("DataCnt");
  4053. OffsetValue = processParam.Value<double>("OffsetValue");
  4054. judgmentData = (DataJudgment)processParam.Value<int>("JudgmentData");
  4055. TensionProp TensionParam = JsonConvert.DeserializeObject<TensionProp>(jsonParams);
  4056. //显示当前测试
  4057. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "张力读取", lstTension, 0, 0, 0, 1, false));
  4058. while (true)
  4059. {
  4060. if (isBreakProcessRun())
  4061. return stepIndex;
  4062. bool sts = false;
  4063. double tensionValue = 0;
  4064. double tensionJudgValue = 0;
  4065. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.触发张力), GetIOBitIndex((int)DIName.触发张力), out sts);
  4066. if( sts )
  4067. {
  4068. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.触发张力按钮灯), GetIOBitIndex((int)DOName.触发张力按钮灯), true);
  4069. tempDataList = new List<double>();
  4070. for (int i = 0; i < DataCnt; i++)
  4071. {
  4072. //Thread.Sleep(DelayTime);
  4073. Thread.Sleep(100);
  4074. tensionValue = TensionGetValueNewStep();
  4075. if (tensionValue < 0)
  4076. {
  4077. if(tensionValue == -1)
  4078. Log("张力读取", "张力读取失败,忽略此次测试!");
  4079. else
  4080. Log("张力读取", "张力读取失败且处理失败,忽略此次测试!");
  4081. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.触发张力按钮灯), GetIOBitIndex((int)DOName.触发张力按钮灯), false);
  4082. return stepIndex;
  4083. }
  4084. tempDataList.Add( tensionValue );
  4085. }
  4086. switch(dataProcess)
  4087. {
  4088. case DataProcess.均值:
  4089. tensionValue = tempDataList.Average();
  4090. break;
  4091. case DataProcess.最大值:
  4092. tensionValue = tempDataList.Max();
  4093. break;
  4094. case DataProcess.最小值:
  4095. tensionValue = tempDataList.Min();
  4096. break;
  4097. default:
  4098. tensionValue = tempDataList.Average();
  4099. Log("张力读取", "张力读取处理错误,启用均值!");
  4100. break;
  4101. }
  4102. tensionValue = Math.Round(tensionValue, 2);
  4103. Log("张力读取", $"张力值:{tensionValue}, 补偿值:{OffsetValue}");
  4104. tensionValue = tensionValue + OffsetValue;
  4105. lstTension.Add(tensionValue);
  4106. Thread.Sleep(200);
  4107. //获取判断结果
  4108. if (judgmentData == DataJudgment.单点)
  4109. tensionJudgValue = tensionValue;
  4110. else
  4111. tensionJudgValue = Math.Round(lstTension.Average(), 2);
  4112. if (TensionParam.OpenUseLimit)
  4113. {
  4114. upLimit = TensionParam.StandardValues + TensionParam.MaxLimit;
  4115. loLimit = TensionParam.StandardValues - TensionParam.MinLimit;
  4116. }
  4117. else
  4118. {
  4119. upLimit = CurrProductModel.TensionBaseValue + CurrProductModel.TensionUpFloatValue;
  4120. loLimit = CurrProductModel.TensionBaseValue - CurrProductModel.TensionDownFloatValue;
  4121. }
  4122. if (((upLimit+ loLimit)>0)&&(tensionJudgValue > upLimit) || (tensionJudgValue < loLimit))
  4123. {
  4124. CurrStepResult = 2;
  4125. //order.Qualified = false;
  4126. }
  4127. else if ((judgmentData == DataJudgment.均值)
  4128. && (upLimit + loLimit > 0 && !(tensionJudgValue > upLimit || tensionJudgValue < loLimit)))
  4129. {
  4130. //order.Qualified = true;
  4131. CurrStepResult = 0;
  4132. }
  4133. order.TensionValue = Math.Round(lstTension.Average(),2);
  4134. if (order.SizeDefectInfoList == null)
  4135. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  4136. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  4137. {
  4138. result = CurrStepResult == 2 ? 2:1,
  4139. X = 0,
  4140. Y = 0,
  4141. PointCode = processInfo.ProcessCode,
  4142. Data = tensionValue,
  4143. StepName = processName,
  4144. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4145. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4146. isAverage = false
  4147. });
  4148. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.触发张力按钮灯), GetIOBitIndex((int)DOName.触发张力按钮灯), false);
  4149. //显示数据
  4150. if ((TestCnt - 1) == this.CurrPoinntCount) //显示最终结果
  4151. {
  4152. order.Qualified = CurrStepResult > 0 ? false : order.Qualified;
  4153. //记录均值
  4154. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  4155. {
  4156. result = CurrStepResult == 2 ? 2 : 1,
  4157. X = 0,
  4158. Y = 0,
  4159. PointCode = processInfo.ProcessCode,
  4160. Data = Math.Round(lstTension.Average(), 2),
  4161. StepName = processName,
  4162. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4163. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4164. isAverage = true
  4165. });
  4166. //打印
  4167. PrintDataList(processName, TensionParam, CurrProductModel.TensionBaseValue, CurrProductModel.TensionUpFloatValue, CurrProductModel.TensionDownFloatValue);
  4168. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "张力读取", lstTension, Math.Round(lstTension.Average(), 2),
  4169. Math.Round(lstTension.Max(), 2), Math.Round(lstTension.Min(), 2), CurrStepResult > 0 ? 3 : 2, false));
  4170. }
  4171. else
  4172. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "张力读取", lstTension, Math.Round(lstTension.Average(), 2),
  4173. Math.Round(lstTension.Max(), 2), Math.Round(lstTension.Min(), 2), 1, false));
  4174. break;
  4175. }
  4176. Thread.Sleep(100);
  4177. }
  4178. Thread.Sleep(DelayTime);
  4179. #endregion
  4180. break;
  4181. case "Height":
  4182. #region 厚度测试
  4183. if (confMgr.SysConfigParams.DisableThickness)
  4184. {
  4185. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4186. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4187. break;
  4188. }
  4189. if (!SizeEnable)
  4190. {
  4191. Log($"{stepIndex + 1}-{processName}", $"尺寸检测功能禁用,忽略此步骤!");
  4192. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"尺寸检测功能禁用,忽略此步骤!", 0, false));
  4193. break;
  4194. }
  4195. //判断厚度基准打完
  4196. while (true)
  4197. {
  4198. if (isBreakProcessRun())
  4199. return stepIndex;
  4200. if (IsCurrHeightBase)
  4201. break;
  4202. Thread.Sleep(100);
  4203. }
  4204. //判断是否需要使用双控
  4205. if(!WaitGetStartSig())
  4206. {
  4207. return stepIndex;
  4208. }
  4209. if (!WaitAllAxisDone())//因启用轴异步功能,使用前需等待
  4210. {
  4211. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  4212. return stepIndex;
  4213. }
  4214. TestCnt = processParam.Value<int>("TestCnt");
  4215. dataProcess = (DataProcess)processParam.Value<int>("ProcessData");
  4216. judgmentData = (DataJudgment)processParam.Value<int>("JudgmentData");
  4217. DelayTime = processParam.Value<int>("DelayTime");
  4218. DataCnt = processParam.Value<int>("DataCnt");
  4219. OffsetValue = processParam.Value<double>("OffsetValue");
  4220. //Points = processParam.Value<List<PointF>>("Points");
  4221. ThicknessProp thicknessParam = JsonConvert.DeserializeObject<ThicknessProp>(jsonParams);
  4222. Points = thicknessParam.Points;
  4223. VelLow = processParam.Value<double>("VelLow");
  4224. VelHigh = processParam.Value<double>("VelHigh");
  4225. Acc = processParam.Value<double>("Acc");
  4226. Dec = processParam.Value<double>("Dec");
  4227. WaitTime = processParam.Value<int>("WaitTime");
  4228. ThicknessProp ThicknessParam = JsonConvert.DeserializeObject<ThicknessProp>(jsonParams);
  4229. Log($"{stepIndex + 1}-{processName}", processParam.ToString());
  4230. if (TestCnt > Points.Count)
  4231. {
  4232. Log($"{stepIndex + 1}-{processName}", $"点位少于测试次数!", WarningEnum.High);
  4233. return stepIndex;
  4234. }
  4235. Log($"{stepIndex + 1}-{processName}", $"点位{this.CurrPoinntCount + 1}测试");
  4236. Log($"{stepIndex + 1}-{processName}",
  4237. $"XY准备(绝对)运动至{Points[this.CurrPoinntCount].X},{Points[this.CurrPoinntCount].Y}...");
  4238. if (axisDev.CheckDone(AxisX1, 20) != 0)
  4239. {
  4240. Log($"{stepIndex + 1}-{processName}", $"轴X1到位失败!", WarningEnum.High);
  4241. return stepIndex;
  4242. }
  4243. if (axisDev.CheckDone(AxisY, 20) != 0)
  4244. {
  4245. Log($"{stepIndex + 1}-{processName}", $"轴Y到位失败!", WarningEnum.High);
  4246. return stepIndex;
  4247. }
  4248. VelocityCurveParams velx = new VelocityCurveParams(Acc, Dec, VelLow, VelHigh, MotionST, GetMMtoPlus((AxisName)AxisX1));
  4249. VelocityCurveParams vely = new VelocityCurveParams(Acc, Dec, VelLow, VelHigh, MotionST, GetMMtoPlus((AxisName)AxisY));
  4250. int iret1 = 0;
  4251. int iret2 = 0;
  4252. iret1 = axisDev.MoveAbsValue(AxisX1, velx, Points[this.CurrPoinntCount].X);
  4253. iret2 = axisDev.MoveAbsValue(AxisY, vely, Points[this.CurrPoinntCount].Y);
  4254. if (iret1 != 0)
  4255. {
  4256. Log($"{stepIndex + 1}-{processName}", $"轴X1运动失败!", WarningEnum.High);
  4257. return stepIndex;
  4258. }
  4259. if (iret2 != 0)
  4260. {
  4261. Log($"{stepIndex + 1}-{processName}", $"轴Y运动失败!", WarningEnum.High);
  4262. return stepIndex;
  4263. }
  4264. //多轴同时运行后强制等待各轴完成
  4265. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  4266. if (axisDev.CheckDone(AxisX1, 20) != 0)
  4267. {
  4268. Log($"{stepIndex + 1}-{processName}", $"轴X1到位失败!", WarningEnum.High);
  4269. return stepIndex;
  4270. }
  4271. if (axisDev.CheckDone(AxisY, 20) != 0)
  4272. {
  4273. Log($"{stepIndex + 1}-{processName}", $"轴Y到位失败!", WarningEnum.High);
  4274. return stepIndex;
  4275. }
  4276. Thread.Sleep(WaitTime);
  4277. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  4278. //测厚气缸下降
  4279. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), true);
  4280. Thread.Sleep(confMgr.HeightDoWait);
  4281. //读取数据
  4282. double TempVal = 0;
  4283. tempDataList = new List<double>();
  4284. for (int j = 0; j < DataCnt; j++)
  4285. {
  4286. Thread.Sleep(DelayTime);
  4287. TempVal = thicknessDev.GetValue();
  4288. tempDataList.Add(TempVal);
  4289. }
  4290. switch (dataProcess)
  4291. {
  4292. case DataProcess.均值:
  4293. TempVal = tempDataList.Average();
  4294. break;
  4295. case DataProcess.最大值:
  4296. TempVal = tempDataList.Max();
  4297. break;
  4298. case DataProcess.最小值:
  4299. TempVal = tempDataList.Min();
  4300. break;
  4301. default:
  4302. TempVal = tempDataList.Average();
  4303. Log("厚度读取", "厚度读取处理错误,启用均值!");
  4304. break;
  4305. }
  4306. TempVal = Math.Round(TempVal, 2);
  4307. double TestValue = Math.Round(Math.Abs(lstHeightBase[this.CurrPoinntCount] - TempVal) + OffsetValue,2);
  4308. Log("厚度读取", $"厚度值{this.CurrPoinntCount + 1}:{TestValue},读取值:{TempVal},基准值:{lstHeightBase[this.CurrPoinntCount]},补偿值:{OffsetValue}");
  4309. lstHeight.Add(TestValue);
  4310. //测厚气缸上升
  4311. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), false);
  4312. Thread.Sleep(confMgr.HeightDoWait);
  4313. //获取判断结果
  4314. double JudgValue;
  4315. if (judgmentData == DataJudgment.单点)
  4316. JudgValue = TestValue;
  4317. else
  4318. JudgValue = Math.Round(lstHeight.Average(), 2);
  4319. if (ThicknessParam.OpenUseLimit)
  4320. {
  4321. upLimit = ThicknessParam.StandardValues + ThicknessParam.MaxLimit;
  4322. loLimit = ThicknessParam.StandardValues - ThicknessParam.MinLimit;
  4323. }
  4324. else
  4325. {
  4326. upLimit = CurrProductModel.HeightBaseValue + CurrProductModel.HeightUpFloatValue;
  4327. loLimit = CurrProductModel.HeightBaseValue - CurrProductModel.HeightDownFloatValue;
  4328. }
  4329. if (((upLimit + loLimit) > 0) && (JudgValue > upLimit) || (JudgValue < loLimit))
  4330. {
  4331. CurrStepResult = 2;
  4332. //order.Qualified = false;
  4333. }
  4334. else if ((judgmentData == DataJudgment.均值)
  4335. && (upLimit + loLimit > 0 && !(JudgValue > upLimit || JudgValue < loLimit)))
  4336. {
  4337. //order.Qualified = true;
  4338. CurrStepResult = 0;
  4339. }
  4340. order.HeightValue = Math.Round(lstHeight.Average(),2);
  4341. if (order.SizeDefectInfoList == null)
  4342. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  4343. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  4344. {
  4345. result = CurrStepResult == 2 ? 2 : 1,
  4346. X = Points[this.CurrPoinntCount].X,
  4347. Y = Points[this.CurrPoinntCount].Y,
  4348. PointCode = processInfo.ProcessCode,
  4349. Data = TestValue,
  4350. StepName = processName,
  4351. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4352. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4353. isAverage = false
  4354. });
  4355. //显示数据
  4356. if ((TestCnt - 1) == this.CurrPoinntCount) //显示最终结果
  4357. {
  4358. order.Qualified = CurrStepResult > 0 ? false : order.Qualified;
  4359. //记录均值
  4360. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  4361. {
  4362. result = CurrStepResult == 2 ? 2 : 1,
  4363. X = Points[this.CurrPoinntCount].X,
  4364. Y = Points[this.CurrPoinntCount].Y,
  4365. PointCode = processInfo.ProcessCode,
  4366. Data = Math.Round(lstHeight.Average(), 2),
  4367. StepName = processName,
  4368. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4369. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  4370. isAverage = true
  4371. });
  4372. //打印记录
  4373. PrintDataList(processName, thicknessParam, CurrProductModel.HeightBaseValue, CurrProductModel.HeightUpFloatValue,
  4374. CurrProductModel.HeightDownFloatValue);
  4375. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "厚度读取", lstHeight, Math.Round(lstHeight.Average(), 2),
  4376. Math.Round(lstHeight.Max(), 2), Math.Round(lstHeight.Min(), 2), CurrStepResult > 0 ? 3 : 2, false));
  4377. }
  4378. else
  4379. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "厚度读取", lstHeight, Math.Round(lstHeight.Average(), 2),
  4380. Math.Round(lstHeight.Max(), 2), Math.Round(lstHeight.Min(), 2), 1, false));
  4381. #endregion
  4382. break;
  4383. case "LensMotor":
  4384. #region 镜头
  4385. if (confMgr.SysConfigParams.DisableLensMotor)
  4386. {
  4387. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4388. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4389. break;
  4390. }
  4391. LensProp lensParam = JsonConvert.DeserializeObject<LensProp>(jsonParams);
  4392. //无点位,所以设置为1次执行或0次
  4393. TestCnt = 0;
  4394. //判断是否需要使用双控
  4395. if (!WaitGetStartSig())
  4396. {
  4397. return stepIndex;
  4398. }
  4399. //显示当前测试
  4400. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "镜头变焦", new List<double>(),
  4401. lensParam.AutoFocus ? 0 : 1, lensParam.AutoMotor ? 0 : 1, lensParam.AutoZPoints ? 0 : 1, 1, false));
  4402. //开启自动变倍
  4403. if (lensParam.AutoMotor)
  4404. {
  4405. Log($"{stepIndex + 1}-{processName}", $"开始自动变倍,由起始位置{lensMotorDev.GetFeedbackPos(0)}运动到{lensParam.FcousPos}...");
  4406. lensMotorDev.MoveAbsPulse(0, new VelocityCurveParams(), (int)lensParam.FcousPos);
  4407. }
  4408. else
  4409. {
  4410. Log($"{stepIndex + 1}-{processName}", $"开始手动变倍,由起始位置{lensMotorDev.GetFeedbackPos(0)}运动到{lensParam.MotorPulse}...");
  4411. lensMotorDev.MoveAbsPulse(0, new VelocityCurveParams(), lensParam.MotorPulse);
  4412. }
  4413. VelocityCurveParams vel_z = new VelocityCurveParams(DefaultSpeed / 2, DefaultSpeed / 2, 0, DefaultSpeed / 2, 1, GetMMtoPlus(AxisName.Axis3));
  4414. //开启自动对焦
  4415. if (lensParam.AutoZPoints)
  4416. {
  4417. double zpos = 0;
  4418. switch (lensParam.FcousPos)
  4419. {
  4420. case SmallAxCmdPos.倍率0_58X:
  4421. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_0_58X;
  4422. break;
  4423. case SmallAxCmdPos.倍率1_0X:
  4424. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_1_0X;
  4425. break;
  4426. case SmallAxCmdPos.倍率1_5X:
  4427. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_1_5X;
  4428. break;
  4429. case SmallAxCmdPos.倍率2_0X:
  4430. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_2_0X;
  4431. break;
  4432. case SmallAxCmdPos.倍率2_5X:
  4433. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_2_5X;
  4434. break;
  4435. case SmallAxCmdPos.倍率3_0X:
  4436. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_3_0X;
  4437. break;
  4438. case SmallAxCmdPos.倍率3_5X:
  4439. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_3_5X;
  4440. break;
  4441. case SmallAxCmdPos.倍率4_0X:
  4442. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_4_0X;
  4443. break;
  4444. case SmallAxCmdPos.倍率4_5X:
  4445. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_4_5X;
  4446. break;
  4447. case SmallAxCmdPos.倍率5_0X:
  4448. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_5_0X;
  4449. break;
  4450. case SmallAxCmdPos.倍率5_5X:
  4451. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_5_5X;
  4452. break;
  4453. case SmallAxCmdPos.倍率6_0X:
  4454. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_6_0X;
  4455. break;
  4456. case SmallAxCmdPos.倍率6_5X:
  4457. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_6_5X;
  4458. break;
  4459. case SmallAxCmdPos.倍率7_0X:
  4460. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_7_0X;
  4461. break;
  4462. case SmallAxCmdPos.倍率7_5X:
  4463. zpos = confMgr.SysConfigParams.LensAxisZPos.Z_7_5X;
  4464. break;
  4465. default:
  4466. zpos = 0;
  4467. break;
  4468. }
  4469. Log($"{stepIndex + 1}-{processName}", $"开始自动Z轴对焦,运动到{zpos}...");
  4470. axisDev.MoveAbsValue(AxisZ, vel_z, zpos);
  4471. }
  4472. else
  4473. {
  4474. Log($"{stepIndex + 1}-{processName}", $"开始手动Z轴对焦,运动到{lensParam.ZPoints}...");
  4475. axisDev.MoveAbsValue(AxisZ, vel_z, lensParam.ZPoints);
  4476. }
  4477. //判断到位
  4478. lensMotorDev.CheckDone(0, 10000);
  4479. if (axisDev.CheckDone(AxisZ, 20) != 0)
  4480. {
  4481. Log($"{stepIndex + 1}-{processName}", $"轴Z到位失败!", WarningEnum.High);
  4482. return stepIndex;
  4483. }
  4484. Log($"{stepIndex + 1}-{processName}", $"运动完成,当前镜头位置:{lensMotorDev.GetFeedbackPos(0)},Z轴位置:{axisDev.GetFeedbackPos(AxisZ)/ GetMMtoPlus(AxisName.Axis3)}");
  4485. //自动对焦,开启后之后测试启用
  4486. this.IsAutoFocus = lensParam.AutoFocus;
  4487. this.FocusStep = lensParam.FocusStep;
  4488. this.DirStep = lensParam.DirStep;
  4489. this.DirWaitTime = lensParam.WaitTime;
  4490. this.FocusTimeOut = lensParam.TimeOut;
  4491. //显示完成
  4492. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "镜头变焦", new List<double>(),
  4493. lensParam.AutoFocus ? 0 : 1, lensParam.AutoMotor ? 0 : 1, lensParam.AutoZPoints ? 0 : 1, 2, false));
  4494. #endregion
  4495. break;
  4496. case "Light":
  4497. #region 光源
  4498. if (confMgr.SysConfigParams.DisableLight)
  4499. {
  4500. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4501. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4502. break;
  4503. }
  4504. //判断是否需要使用双控
  4505. if (!WaitGetStartSig())
  4506. {
  4507. return stepIndex;
  4508. }
  4509. //无点位,所以设置为1次执行或0次
  4510. TestCnt = 0;
  4511. LightProp lightParam = JsonConvert.DeserializeObject<LightProp>(jsonParams);
  4512. //显示当前测试
  4513. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "光源设置", new List<double>(), 0, lightParam.ChannelIndex, lightParam.DigitalValue, 1, false));
  4514. int nowDiaitalValue = lightDev.GetLightDigitalValue(lightParam.ChannelIndex);
  4515. Log($"{stepIndex + 1}-{processName}", $"通道{lightParam.ChannelIndex}当前值:{nowDiaitalValue},准备更新值:{lightParam.DigitalValue}...");
  4516. lightDev.SetLightDigitalValue(lightParam.ChannelIndex, lightParam.DigitalValue);
  4517. nowDiaitalValue = lightDev.GetLightDigitalValue(lightParam.ChannelIndex);
  4518. Log($"{stepIndex + 1}-{processName}", $"通道{lightParam.ChannelIndex}更新后当前值:{nowDiaitalValue}。");
  4519. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "光源设置", new List<double>(), 0, lightParam.ChannelIndex, lightParam.DigitalValue, 2, false));
  4520. #endregion
  4521. break;
  4522. case "Mark":
  4523. #region Mark
  4524. MarkProp markParam = JsonConvert.DeserializeObject<MarkProp>(jsonParams);
  4525. if (((confMgr.SysConfigParams.DisableFrontCam)&&(markParam.MarkType == MarkCam.尺寸检测Mark))||
  4526. ((confMgr.SysConfigParams.DisableBackCam) && (markParam.MarkType == MarkCam.缺陷检测Mark)))
  4527. {
  4528. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4529. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4530. break;
  4531. }
  4532. if ((!SizeEnable)&& (markParam.MarkType == MarkCam.尺寸检测Mark))
  4533. {
  4534. Log($"{stepIndex + 1}-{processName}", $"尺寸检测功能禁用,忽略此步骤!");
  4535. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"尺寸检测功能禁用,忽略此步骤!", 0, false));
  4536. break;
  4537. }
  4538. if ((!DefectEnable) && (markParam.MarkType == MarkCam.缺陷检测Mark))
  4539. {
  4540. Log($"{stepIndex + 1}-{processName}", $"缺陷检测功能禁用,忽略此步骤!");
  4541. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"缺陷检测功能禁用,忽略此步骤!", 0, false));
  4542. break;
  4543. }
  4544. //测试4个mark
  4545. TestCnt = markParam.MarkCnt;
  4546. //判断是否需要使用双控
  4547. if (!WaitGetStartSig())
  4548. {
  4549. return stepIndex;
  4550. }
  4551. //获取之后需计算的手选点位
  4552. //Y轴方向PT值检测
  4553. //线宽正面
  4554. //反面检测
  4555. //X轴方向PT值检测
  4556. //主栅连接线检测
  4557. //主栅宽度检测
  4558. //主栅间距
  4559. //细栅间距检测
  4560. //背极宽度
  4561. List<double> posList = new List<double>();
  4562. double[] posArray = null;
  4563. //string[] pointType = new string[17] { "Y轴方向PT值检测" , "线宽正面" , "反面检测" ,
  4564. //"X轴方向PT值检测","主栅连接线检测","主栅宽度检测","主栅间距","细栅间距检测","背极宽度",
  4565. //"主栅长度检测","Mark点横向间距","Mark点竖向间距","鱼叉口长","鱼叉口宽","鱼叉口间距",
  4566. //"蜈蚣角长", "蜈蚣角宽"};
  4567. string[] pointType = testLabels.ToArray();
  4568. int[] adaqter = new int[pointType.Length];
  4569. if (markParam.AutoMark)
  4570. {
  4571. for (int i = 0; i < pointType.Length; i++)
  4572. {
  4573. List<TestDefectPoints> t1 = model.TestDefectPointsList.Where(q => q.PointCode == pointType[i]).ToList();
  4574. if (t1.Count > 0)
  4575. {
  4576. if (pointType[i] == "Y轴方向PT值检测" || pointType[i] == "X轴方向PT值检测")
  4577. adaqter[i] = t1.Count;
  4578. else
  4579. adaqter[i] = t1.Count * 2;
  4580. //添加点位
  4581. for (int j = 0; j < t1.Count; j++)
  4582. {
  4583. if (t1[j].PointCode == "Y轴方向PT值检测")
  4584. posList.Add(t1[j].X);
  4585. else if (t1[j].PointCode == "X轴方向PT值检测")
  4586. posList.Add(t1[j].Y);
  4587. else
  4588. {
  4589. posList.Add(t1[j].X);
  4590. posList.Add(t1[j].Y);
  4591. }
  4592. }
  4593. }
  4594. }
  4595. }
  4596. else
  4597. {
  4598. ;
  4599. }
  4600. CurrAdaqter = adaqter;
  4601. if (posList.Count >0)
  4602. { posArray = posList.ToArray(); }
  4603. //对应运动轴
  4604. List<int> AxisIndexList = new List<int>();
  4605. if (markParam.MarkType == MarkCam.尺寸检测Mark)
  4606. {
  4607. AxisIndexList.Add(AxisX1);
  4608. AxisIndexList.Add(AxisY);
  4609. }
  4610. else
  4611. {
  4612. AxisIndexList.Add(AxisX2);
  4613. AxisIndexList.Add(AxisY);
  4614. }
  4615. //图纸判断
  4616. string typrstr = markParam.MarkType == MarkCam.尺寸检测Mark ? "尺寸检测Mark" : "缺陷检测Mark";
  4617. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  4618. Log($"{stepIndex + 1}-{processName}", $"Mark检测,Mark类型:{typrstr},{model.AttachmentList.Count}|{(attachmentFile == null ? "null" : attachmentFile.NameTimestamp + attachmentFile.ExtendName)}");
  4619. if (attachmentFile != null)
  4620. {
  4621. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  4622. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName))
  4623. gbxBmpPath = "";
  4624. }
  4625. if (gbxBmpPath == "")
  4626. {
  4627. Log($"{stepIndex + 1}-{processName}", $"Mark检测,Mark类型:{typrstr},图纸不存在!", WarningEnum.High);
  4628. return stepIndex;
  4629. }
  4630. if (this.CurrPoinntCount == 0) //第一点开始
  4631. {
  4632. //传图获取Mark位置,图片大小确定是哪个相机
  4633. HObject markImg;
  4634. string backPath = confMgr.MarkPicPath + (markParam.MarkType == MarkCam.尺寸检测Mark? "\\3333_尺寸.bmp" : "\\3333_缺陷.bmp");
  4635. HOperatorSet.ReadImage(out markImg, backPath);
  4636. OnAutoRuning(new RunEventArgs(stepIndex, "Mark寻找", new List<double>(), 0, 0, 0, 1, false));
  4637. bool isGetMarkPos = GetMarkPoints(true,this.CurrPoinntCount, model.StepInfo.Name,
  4638. stepIndex, processName, markParam.MarkType, markParam.EngineName, markImg.Clone(), gbxBmpPath, adaqter, posArray, false);
  4639. if(!isGetMarkPos)
  4640. {
  4641. //自动获取mark失败
  4642. Log($"{stepIndex + 1}-{processName}", $"Mark位置获取等待超时!", WarningEnum.High);
  4643. return stepIndex;
  4644. }
  4645. }
  4646. //根据mark寻找trg
  4647. //判断有无tag
  4648. if (order.SizeTagDataList == null)
  4649. {
  4650. Log($"{stepIndex + 1}-{processName}", $"Mark数据提供者Tag为空!", WarningEnum.High);
  4651. return stepIndex;
  4652. }
  4653. //tag
  4654. string MarkTag = "";
  4655. if (markParam.MarkType == MarkCam.尺寸检测Mark)
  4656. MarkTag = "F_Mark_" + stepIndex;
  4657. else
  4658. MarkTag = "B_Mark_" + stepIndex;
  4659. //用最新的last
  4660. var sizeTagObj = order.SizeTagDataList.LastOrDefault(m => m.SizeTag == MarkTag);
  4661. if (sizeTagObj == null)
  4662. {
  4663. Log($"{stepIndex + 1}-{processName}", $"未找到自动获取的Mark数据!", WarningEnum.High);
  4664. return stepIndex;
  4665. }
  4666. string[] posePT = sizeTagObj.posePT.Split(',');
  4667. if (posePT.Length < this.CurrPoinntCount * 2 + 2)
  4668. {
  4669. Log($"{stepIndex + 1}-{processName}",
  4670. $"MarkTag对应消费索引:{this.CurrPoinntCount * 2},Axis数量:{2} 超出postPT:{sizeTagObj.posePT} 范围!", WarningEnum.High);
  4671. return stepIndex;
  4672. }
  4673. //交换点位顺序1-2-3-4 =》 1-2-4-3
  4674. string tempPosStr = posePT[4];
  4675. posePT[4] = posePT[6];
  4676. posePT[6] = tempPosStr;
  4677. tempPosStr = posePT[5];
  4678. posePT[5] = posePT[7];
  4679. posePT[7] = tempPosStr;
  4680. //轴运动
  4681. double[] TagPPUValue = new double[AxisIndexList.Count];
  4682. for (int i = 0; i < AxisIndexList.Count; i++)
  4683. TagPPUValue[i] = double.Parse(posePT[this.CurrPoinntCount * 2 + i]);
  4684. for (int i = 0; i < TagPPUValue.Length; i++)
  4685. {
  4686. if (axisDev.CheckDone(AxisIndexList[i], 60) != 0)
  4687. {
  4688. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}到位失败!", WarningEnum.High);
  4689. return stepIndex;
  4690. }
  4691. VelocityCurveParams vel = new VelocityCurveParams(markParam.Acc, markParam.Dec, markParam.VelLow, markParam.VelHigh, MotionST, GetMMtoPlus((AxisName)AxisIndexList[i]));
  4692. int iret = 0;
  4693. iret = axisDev.MoveAbsValue(AxisIndexList[i], vel, TagPPUValue[i]);
  4694. if (iret != 0)
  4695. {
  4696. Log($"{stepIndex + 1}-{processName}", $"轴{AxisIndexList[i]}运动失败!", WarningEnum.High);
  4697. return stepIndex;
  4698. }
  4699. }
  4700. if (sizeTagObj.ConsumeStepIndex == null)
  4701. sizeTagObj.ConsumeStepIndex = "";
  4702. sizeTagObj.ConsumeStepIndex += $"{stepIndex + 1}-{this.CurrPoinntCount}, ";//消费工序ID
  4703. //多轴同时运行后强制等待各轴完成
  4704. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  4705. if (!WaitAxisDone(AxisIndexList))
  4706. {
  4707. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  4708. return stepIndex;
  4709. }
  4710. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  4711. Thread.Sleep(markParam.WaitTime);
  4712. //自动聚焦?
  4713. if (markParam.MarkType == MarkCam.尺寸检测Mark)
  4714. {
  4715. CamDevFront.SetExposure(markParam.ExposureTime);
  4716. CamDevFront.SetGain(markParam.Gain);
  4717. }
  4718. if ((this.CurrPoinntCount == 0)&&(IsAutoFocus)&& (markParam.MarkType == MarkCam.尺寸检测Mark))
  4719. {
  4720. Log($"{stepIndex + 1}-{processName}", $"自动聚焦...");
  4721. if(!AutoFocus(FocusStep, DirStep, DirWaitTime, FocusTimeOut))
  4722. {
  4723. Log($"{stepIndex + 1}-{processName}", $"自动聚焦失败!", WarningEnum.High);
  4724. return stepIndex;
  4725. }
  4726. Log($"{stepIndex + 1}-{processName}", $"自动聚焦完成");
  4727. }
  4728. //拍照处理
  4729. HObject DefLastImg = new HObject(); //缺陷左上角使用
  4730. Log($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  4731. if (markParam.MarkType == MarkCam.尺寸检测Mark)
  4732. {
  4733. //CamDevFront.SetExposure(markParam.ExposureTime);
  4734. //CamDevFront.SetGain(markParam.Gain);
  4735. Log($"{stepIndex + 1}-{processName}", $"相机参数设置完成。");
  4736. DateTime dt0 = DateTime.Now;
  4737. CamDevFront.ClearImageQueue();
  4738. Acquisition acq0 = CamDevFront.Snap(1, 5000);
  4739. if (acq0.GrabStatus != "GrabPass")
  4740. {
  4741. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片失败!", WarningEnum.High);
  4742. return stepIndex;
  4743. }
  4744. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片完成[" + (DateTime.Now - dt0).Milliseconds.ToString() + "ms]");
  4745. //显示
  4746. OnAutoRuning(new RunEventArgs(0, acq0.Image));
  4747. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  4748. acq0.Image.Clone(),
  4749. GetAxisPosValueMM((int)AxisName.Axis0),
  4750. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  4751. Log($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列," +
  4752. $"X:{GetAxisPosValueMM((int)AxisName.Axis0)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  4753. $"数量: {scannerCBmpQueue.Count}");
  4754. }
  4755. else
  4756. {
  4757. CamDevBack.SetExposure(markParam.ExposureTime);
  4758. CamDevBack.SetGain(markParam.Gain);
  4759. DateTime dt = DateTime.Now;
  4760. CamDevBack.ClearImageQueue();
  4761. Acquisition acq = CamDevBack.Snap(1, 5000);
  4762. if (acq.GrabStatus != "GrabPass")
  4763. {
  4764. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片失败!", WarningEnum.High);
  4765. return stepIndex;
  4766. }
  4767. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片完成[" + (DateTime.Now - dt).Milliseconds.ToString() + "ms]");
  4768. //显示
  4769. OnAutoRuning(new RunEventArgs(1, acq.Image));
  4770. //----缺陷队列
  4771. DefLastImg = acq.Image.Clone();
  4772. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  4773. acq.Image.Clone(),
  4774. GetAxisPosValueMM((int)AxisName.Axis1),
  4775. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  4776. Log($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列," +
  4777. $"X:{GetAxisPosValueMM((int)AxisName.Axis1)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  4778. $"数量: {scannerCBmpQueue.Count}");
  4779. }
  4780. //mark计算
  4781. bool tRet = GetMarkPoints(false, this.CurrPoinntCount, model.StepInfo.Name,
  4782. stepIndex, processName, markParam.MarkType, markParam.EngineName,
  4783. null, gbxBmpPath, adaqter, posArray, (this.CurrPoinntCount + 1) == TestCnt?false:true);
  4784. if (!tRet)
  4785. {
  4786. //自动获取mark失败
  4787. Log($"{stepIndex + 1}-{processName}", $"Mark位置获取等待超时!", WarningEnum.High);
  4788. return stepIndex;
  4789. }
  4790. //最后判断
  4791. if((this.CurrPoinntCount + 1) == TestCnt)
  4792. {
  4793. if(markParam.MarkType == MarkCam.缺陷检测Mark)
  4794. {
  4795. //缺陷获取左上角位置
  4796. bool isGetMarkPos = GetMarkPoints(true, this.CurrPoinntCount, model.StepInfo.Name,
  4797. stepIndex, processName, markParam.MarkType, markParam.EngineName, DefLastImg.Clone(), gbxBmpPath, adaqter, posArray, false);
  4798. if (!isGetMarkPos)
  4799. {
  4800. //自动获取mark失败
  4801. Log($"{stepIndex + 1}-{processName}", $"左上角位置获取等待超时!", WarningEnum.High);
  4802. return stepIndex;
  4803. }
  4804. }
  4805. OnAutoRuning(new RunEventArgs(stepIndex, "Mark寻找", new List<double>(), 0, 0, 0, tRet?2:3, false));
  4806. }
  4807. #endregion
  4808. break;
  4809. case "PointTest":
  4810. #region 尺寸选点测试
  4811. PointTestProp testParam = JsonConvert.DeserializeObject<PointTestProp>(jsonParams);
  4812. if (confMgr.SysConfigParams.DisableFrontCam)
  4813. {
  4814. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  4815. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, false));
  4816. break;
  4817. }
  4818. if (!SizeEnable)
  4819. {
  4820. Log($"{stepIndex + 1}-{processName}", $"尺寸检测功能禁用,忽略此步骤!");
  4821. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"尺寸检测功能禁用,忽略此步骤!", 0, false));
  4822. break;
  4823. }
  4824. //对应运动轴
  4825. List<int> PAxisIndexList = new List<int>();
  4826. PAxisIndexList.Add(AxisX1);
  4827. PAxisIndexList.Add(AxisY);
  4828. double[] TestPosTagPPUValue = new double[PAxisIndexList.Count * 2];
  4829. TestCnt = 0;
  4830. string[] TestPos = new string[1];
  4831. //图纸
  4832. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  4833. Log($"{stepIndex + 1}-{processName}", $"比对图像,{model.AttachmentList.Count}|{(attachmentFile == null ? "null" : attachmentFile.NameTimestamp + attachmentFile.ExtendName)}");
  4834. //自动点位数计算
  4835. if (attachmentFile != null)
  4836. {
  4837. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  4838. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName))
  4839. gbxBmpPath = "";
  4840. }
  4841. if (gbxBmpPath == "")
  4842. {
  4843. Log($"{stepIndex + 1}-{processName}", $"比对图像,图纸不存在!", WarningEnum.High);
  4844. return stepIndex;
  4845. }
  4846. if (!testParam.AutoMark)
  4847. {
  4848. //手动点位数计算
  4849. CurrAdaqter = new int[testLabels.Count];
  4850. CurrAdaqter[(int)testParam.TestType] = testParam.PointCnt;
  4851. }
  4852. //自动寻点
  4853. if ((testParam.AutoMark)|| (testParam.DefPos))
  4854. {
  4855. //判断有无tag
  4856. if (order.SizeTagDataList == null)
  4857. {
  4858. Log($"{stepIndex + 1}-{processName}", $"点位数据提供者Tag为空!", WarningEnum.High);
  4859. return stepIndex;
  4860. }
  4861. //tag
  4862. string TestPosTag = "F_Pos";
  4863. //用最新的last
  4864. var TestPosTagObj = order.SizeTagDataList.LastOrDefault(m => m.SizeTag == TestPosTag);
  4865. if (TestPosTagObj == null)
  4866. {
  4867. Log($"{stepIndex + 1}-{processName}", $"未找到自动获取的测试点位数据!", WarningEnum.High);
  4868. return stepIndex;
  4869. }
  4870. TestPos = TestPosTagObj.posePT.Split(',');
  4871. if ((testParam.DefPos) &&(TestPos.Length < 38))
  4872. {
  4873. Log($"{stepIndex + 1}-{processName}",
  4874. $"自动获取的默认测试点位数据范围错误:{TestPos.Length}!", WarningEnum.High);
  4875. return stepIndex;
  4876. }
  4877. }
  4878. else
  4879. {
  4880. if ((testParam.TestType != PointTestType.线宽正面) && (testParam.TestType != PointTestType.反面检测)
  4881. && (testParam.TestType != PointTestType.背极宽度) && (testParam.TestType != PointTestType.主栅宽度检测
  4882. && (testParam.TestType != PointTestType.鱼叉口宽)) && (testParam.TestType != PointTestType.蜈蚣角宽))
  4883. TestPos = new string[testParam.Points.Count * 4];
  4884. else
  4885. TestPos = new string[testParam.Points.Count * 2];
  4886. for (int i = 0; i < testParam.Points.Count; i++)
  4887. {
  4888. TestPos[2 * i] = testParam.Points[i].X.ToString();
  4889. TestPos[2 * i + 1] = testParam.Points[i].Y.ToString();
  4890. }
  4891. }
  4892. int posIndex = this.CurrPoinntCount;
  4893. //手动顺寻
  4894. if( (!testParam.SelectPoint)&&(testParam.Indexs.Count >= testParam.PointCnt))
  4895. {
  4896. posIndex = testParam.Indexs[this.CurrPoinntCount];
  4897. }
  4898. else if (!testParam.SelectPoint)
  4899. {
  4900. Log($"{stepIndex + 1}-{processName}",
  4901. $"手动测试点位顺序范围错误:{testParam.Indexs.Count}!", WarningEnum.High);
  4902. return stepIndex;
  4903. }
  4904. //判断是否一点完成
  4905. bool IsOverDef = true;
  4906. //是否使用点位判断
  4907. if (testParam.DefPos)
  4908. {
  4909. //使用默认点位测试
  4910. if(this.CurrPoinntCount == 0)
  4911. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"默认位置检测开始...", null, 0, 0, 0, 1, false));
  4912. switch (testParam.TestType) {
  4913. case PointTestType.Y轴方向PT值检测:
  4914. IsOverDef = false;
  4915. TestCnt = testParam.PointCnt;
  4916. if (testParam.PointCnt > 5 )
  4917. {
  4918. Log($"{stepIndex + 1}-{processName}", $"Y轴方向PT值检测参数,默认只支持5点以内!", WarningEnum.High);
  4919. return stepIndex;
  4920. }
  4921. //走位计算
  4922. TestPosTagPPUValue[0] = double.Parse(TestPos[2 * posIndex]);
  4923. TestPosTagPPUValue[1] = double.Parse(TestPos[2 * posIndex + 1]);
  4924. TestPosTagPPUValue[2] = double.Parse(TestPos[2 * posIndex + 10]);
  4925. TestPosTagPPUValue[3] = double.Parse(TestPos[2 * posIndex + 11]);
  4926. break;
  4927. case PointTestType.线宽正面:
  4928. TestCnt = testParam.PointCnt;
  4929. if (TestCnt > 9)
  4930. {
  4931. Log($"{stepIndex + 1}-{processName}", $"线宽正面参数,默认只支持9点以内!", WarningEnum.High);
  4932. return stepIndex;
  4933. }
  4934. //走位计算
  4935. TestPosTagPPUValue[0] = double.Parse(TestPos[20 + 2 * posIndex]);
  4936. TestPosTagPPUValue[1] = double.Parse(TestPos[20 + 2 * posIndex + 1]);
  4937. break;
  4938. case PointTestType.反面检测:
  4939. Log($"{stepIndex + 1}-{processName}", $"反面检测参数不支持默认!", WarningEnum.High);
  4940. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"参数不支持默认!", 4, false));
  4941. return stepIndex;
  4942. case PointTestType.X轴方向PT值检测:
  4943. IsOverDef = false;
  4944. Log($"{stepIndex + 1}-{processName}", $"X轴方向PT值检测参数不支持默认!", WarningEnum.High);
  4945. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"X轴方向PT值检测参数不支持默认!", 4, false));
  4946. return stepIndex;
  4947. case PointTestType.主栅连接线检测:
  4948. Log($"{stepIndex + 1}-{processName}", $"主栅连接线检测参数不支持默认!", WarningEnum.High);
  4949. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"主栅连接线检测参数不支持默认!", 4, false));
  4950. return stepIndex;
  4951. case PointTestType.主栅宽度检测:
  4952. Log($"{stepIndex + 1}-{processName}", $"主栅宽度检测参数不支持默认!", WarningEnum.High);
  4953. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"主栅宽度检测参数不支持默认!", 4, false));
  4954. return stepIndex;
  4955. case PointTestType.主栅间距:
  4956. Log($"{stepIndex + 1}-{processName}", $"主栅间距参数不支持默认!", WarningEnum.High);
  4957. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"主栅间距参数不支持默认!", 4, false));
  4958. return stepIndex;
  4959. case PointTestType.细栅间距检测:
  4960. Log($"{stepIndex + 1}-{processName}", $"细栅间距检测参数不支持默认!", WarningEnum.High);
  4961. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"细栅间距检测参数不支持默认!", 4, false));
  4962. return stepIndex;
  4963. case PointTestType.背极宽度:
  4964. Log($"{stepIndex + 1}-{processName}", $"背极宽度参数不支持默认!", WarningEnum.High);
  4965. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"背极宽度参数不支持默认!", 4, false));
  4966. return stepIndex;
  4967. default:
  4968. Log($"{stepIndex + 1}-{processName}", $"参数不支持!", WarningEnum.High);
  4969. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"参数不支持!", 4, false));
  4970. return stepIndex;
  4971. }
  4972. }
  4973. else
  4974. {
  4975. if (this.CurrPoinntCount == 0)
  4976. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"特定位置检测开始...", null, 0, 0, 0, 1, false));
  4977. /******************key
  4978. * Y轴方向PT值检测
  4979. 线宽正面
  4980. 反面检测
  4981. X轴方向PT值检测
  4982. 主栅连接线检测
  4983. 主栅宽度检测
  4984. 主栅间距
  4985. 细栅间距检测
  4986. 背极宽度
  4987. ******************/
  4988. List<TestDefectPoints> t = new List<TestDefectPoints>();
  4989. switch (testParam.TestType)
  4990. {
  4991. case PointTestType.Y轴方向PT值检测:
  4992. IsOverDef = false;
  4993. TestCnt = testParam.PointCnt;
  4994. t = model.TestDefectPointsList.Where(q => q.PointCode == "Y轴方向PT值检测").ToList();
  4995. if (testParam.AutoMark)
  4996. {
  4997. if (testParam.PointCnt > t.Count)
  4998. {
  4999. Log($"{stepIndex + 1}-{processName}", $"Y轴方向PT值检测参数,点数大于产品配置点数!", WarningEnum.High);
  5000. return stepIndex;
  5001. }
  5002. }
  5003. //走位计算
  5004. TestPosTagPPUValue[0] = double.Parse(TestPos[2 * posIndex]);
  5005. TestPosTagPPUValue[1] = double.Parse(TestPos[2 * posIndex + 1]);
  5006. TestPosTagPPUValue[2] = double.Parse(TestPos[2 * posIndex + this.CurrAdaqter[0] * 2]);
  5007. TestPosTagPPUValue[3] = double.Parse(TestPos[2 * posIndex + this.CurrAdaqter[0] * 2 + 1]);
  5008. break;
  5009. case PointTestType.线宽正面:
  5010. TestCnt = testParam.PointCnt;
  5011. t = model.TestDefectPointsList.Where(q => q.PointCode == "线宽正面").ToList();
  5012. if (testParam.AutoMark)
  5013. if (testParam.PointCnt > t.Count)
  5014. {
  5015. Log($"{stepIndex + 1}-{processName}", $"线宽正面检测参数,点数大于产品配置点数!", WarningEnum.High);
  5016. return stepIndex;
  5017. }
  5018. //走位计算
  5019. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + 2 * posIndex]);
  5020. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + 2 * posIndex + 1]);
  5021. break;
  5022. case PointTestType.反面检测:
  5023. TestCnt = testParam.PointCnt;
  5024. t = model.TestDefectPointsList.Where(q => q.PointCode == "反面检测").ToList();
  5025. if (testParam.AutoMark)
  5026. if (testParam.PointCnt > t.Count)
  5027. {
  5028. Log($"{stepIndex + 1}-{processName}", $"反面检测参数,点数大于产品配置点数!", WarningEnum.High);
  5029. return stepIndex;
  5030. }
  5031. //走位计算
  5032. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1] * 2 + 2 * posIndex]);
  5033. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1] * 2 + 2 * posIndex + 1]);
  5034. break;
  5035. case PointTestType.X轴方向PT值检测:
  5036. IsOverDef = false;
  5037. TestCnt = testParam.PointCnt;
  5038. t = model.TestDefectPointsList.Where(q => q.PointCode == "X轴方向PT值检测").ToList();
  5039. if (testParam.AutoMark)
  5040. if (testParam.PointCnt > t.Count)
  5041. {
  5042. Log($"{stepIndex + 1}-{processName}", $"X轴方向PT值检测参数,点数大于产品配置点数!", WarningEnum.High);
  5043. return stepIndex;
  5044. }
  5045. //走位计算
  5046. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1] + this.CurrAdaqter[2] + 2 * posIndex]);
  5047. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1] + this.CurrAdaqter[2] + 2 * posIndex + 1]);
  5048. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1] + this.CurrAdaqter[2] + 2 * posIndex + this.CurrAdaqter[3] * 2]);
  5049. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1] + this.CurrAdaqter[2] + 2 * posIndex + this.CurrAdaqter[3] * 2 + 1]);
  5050. break;
  5051. case PointTestType.主栅连接线检测:
  5052. IsOverDef = false;
  5053. TestCnt = testParam.PointCnt;
  5054. t = model.TestDefectPointsList.Where(q => q.PointCode == "主栅连接线检测").ToList();
  5055. if (testParam.AutoMark)
  5056. if (testParam.PointCnt > t.Count)
  5057. {
  5058. Log($"{stepIndex + 1}-{processName}", $"主栅连接线检测参数,点数大于产品配置点数!", WarningEnum.High);
  5059. return stepIndex;
  5060. }
  5061. //走位计算
  5062. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5063. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + 4 * posIndex]);
  5064. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5065. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + 4 * posIndex + 1]);
  5066. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5067. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + 4 * posIndex + 2]);
  5068. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5069. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + 4 * posIndex + 3]);
  5070. break;
  5071. case PointTestType.主栅宽度检测:
  5072. IsOverDef = true;
  5073. TestCnt = testParam.PointCnt;
  5074. t = model.TestDefectPointsList.Where(q => q.PointCode == "主栅宽度检测").ToList();
  5075. if (testParam.AutoMark)
  5076. if (testParam.PointCnt > t.Count)
  5077. {
  5078. Log($"{stepIndex + 1}-{processName}", $"主栅宽度检测参数,点数大于产品配置点数!", WarningEnum.High);
  5079. return stepIndex;
  5080. }
  5081. //走位计算
  5082. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5083. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + 2 * posIndex]);
  5084. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5085. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + 2 * posIndex + 1]);
  5086. //TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5087. // + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + 4 * posIndex + 2]);
  5088. //TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5089. // + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + 4 * posIndex + 3]);
  5090. break;
  5091. case PointTestType.主栅间距:
  5092. IsOverDef = false;
  5093. TestCnt = testParam.PointCnt;
  5094. t = model.TestDefectPointsList.Where(q => q.PointCode == "主栅间距").ToList();
  5095. if (testParam.AutoMark)
  5096. if (testParam.PointCnt > t.Count)
  5097. {
  5098. Log($"{stepIndex + 1}-{processName}", $"主栅间距检测参数,点数大于产品配置点数!", WarningEnum.High);
  5099. return stepIndex;
  5100. }
  5101. //走位计算
  5102. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5103. + this.CurrAdaqter[2]+ this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5] + 4 * posIndex]);
  5104. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5105. + this.CurrAdaqter[2]+ this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5] + 4 * posIndex + 1]);
  5106. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5107. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5108. + 4 * posIndex + 2]);
  5109. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5110. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5111. + 4 * posIndex + 3]);
  5112. break;
  5113. case PointTestType.细栅间距检测:
  5114. IsOverDef = false;
  5115. TestCnt = testParam.PointCnt;
  5116. t = model.TestDefectPointsList.Where(q => q.PointCode == "细栅间距检测").ToList();
  5117. if (testParam.AutoMark)
  5118. if (testParam.PointCnt > t.Count)
  5119. {
  5120. Log($"{stepIndex + 1}-{processName}", $"细栅间距检测参数,点数大于产品配置点数!", WarningEnum.High);
  5121. return stepIndex;
  5122. }
  5123. //走位计算
  5124. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5125. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5126. + this.CurrAdaqter[6] + 4 * posIndex]);
  5127. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5128. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5129. + this.CurrAdaqter[6] + 4 * posIndex + 1]);
  5130. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5131. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5132. + this.CurrAdaqter[6] + 4 * posIndex + 2]);
  5133. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5134. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5135. + this.CurrAdaqter[6] + 4 * posIndex + 3]);
  5136. break;
  5137. case PointTestType.背极宽度:
  5138. TestCnt = testParam.PointCnt;
  5139. t = model.TestDefectPointsList.Where(q => q.PointCode == "背极宽度").ToList();
  5140. if (testParam.AutoMark)
  5141. if (testParam.PointCnt > t.Count)
  5142. {
  5143. Log($"{stepIndex + 1}-{processName}", $"背极宽度参数,点数大于产品配置点数!", WarningEnum.High);
  5144. return stepIndex;
  5145. }
  5146. //走位计算
  5147. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5148. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5149. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + 2 * posIndex]);
  5150. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5151. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5152. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + 2 * posIndex + 1]);
  5153. break;
  5154. case PointTestType.主栅长度检测:
  5155. IsOverDef = false;
  5156. TestCnt = testParam.PointCnt;
  5157. t = model.TestDefectPointsList.Where(q => q.PointCode == "主栅长度检测").ToList();
  5158. if (testParam.AutoMark)
  5159. if (testParam.PointCnt > t.Count)
  5160. {
  5161. Log($"{stepIndex + 1}-{processName}", $"主栅长度检测参数,点数大于产品配置点数!", WarningEnum.High);
  5162. return stepIndex;
  5163. }
  5164. //走位计算
  5165. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5166. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5167. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + 4 * posIndex]);
  5168. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5169. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5170. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + 4 * posIndex + 1]);
  5171. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5172. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5173. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + 4 * posIndex
  5174. + 2]);
  5175. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5176. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5177. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + 4 * posIndex
  5178. + 3]);
  5179. break;
  5180. case PointTestType.Mark点横向间距:
  5181. IsOverDef = false;
  5182. TestCnt = testParam.PointCnt;
  5183. t = model.TestDefectPointsList.Where(q => q.PointCode == "Mark点横向间距").ToList();
  5184. if (testParam.AutoMark)
  5185. if (testParam.PointCnt > t.Count)
  5186. {
  5187. Log($"{stepIndex + 1}-{processName}", $"Mark点横向间距参数,点数大于产品配置点数!", WarningEnum.High);
  5188. return stepIndex;
  5189. }
  5190. //走位计算
  5191. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5192. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5193. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5194. + 4 * posIndex]);
  5195. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5196. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5197. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5198. + 4 * posIndex + 1]);
  5199. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5200. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5201. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5202. + 4 * posIndex + 2]);
  5203. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5204. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5205. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5206. + 4 * posIndex + 3]);
  5207. break;
  5208. case PointTestType.Mark点竖向间距:
  5209. IsOverDef = false;
  5210. TestCnt = testParam.PointCnt;
  5211. t = model.TestDefectPointsList.Where(q => q.PointCode == "Mark点竖向间距").ToList();
  5212. if (testParam.AutoMark)
  5213. if (testParam.PointCnt > t.Count)
  5214. {
  5215. Log($"{stepIndex + 1}-{processName}", $"Mark点竖向间距参数,点数大于产品配置点数!", WarningEnum.High);
  5216. return stepIndex;
  5217. }
  5218. //走位计算
  5219. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5220. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5221. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5222. + this.CurrAdaqter[10] + 4 * posIndex]);
  5223. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5224. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5225. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5226. + this.CurrAdaqter[10] + 4 * posIndex + 1]);
  5227. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5228. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5229. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5230. + this.CurrAdaqter[10] + 4 * posIndex + 2]);
  5231. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5232. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5233. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5234. + this.CurrAdaqter[10] + 4 * posIndex + 3]);
  5235. break;
  5236. case PointTestType.鱼叉口长:
  5237. IsOverDef = false;
  5238. TestCnt = testParam.PointCnt;
  5239. t = model.TestDefectPointsList.Where(q => q.PointCode == "鱼叉口长").ToList();
  5240. if (testParam.AutoMark)
  5241. if (testParam.PointCnt > t.Count)
  5242. {
  5243. Log($"{stepIndex + 1}-{processName}", $"鱼叉口长参数,点数大于产品配置点数!", WarningEnum.High);
  5244. return stepIndex;
  5245. }
  5246. //走位计算
  5247. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5248. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5249. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5250. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + 4 * posIndex]);
  5251. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5252. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5253. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5254. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + 4 * posIndex + 1]);
  5255. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5256. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5257. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5258. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + 4 * posIndex + 2]);
  5259. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5260. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5261. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5262. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + 4 * posIndex + 3]);
  5263. break;
  5264. case PointTestType.鱼叉口宽:
  5265. IsOverDef = true;
  5266. TestCnt = testParam.PointCnt;
  5267. t = model.TestDefectPointsList.Where(q => q.PointCode == "鱼叉口宽").ToList();
  5268. if (testParam.AutoMark)
  5269. if (testParam.PointCnt > t.Count)
  5270. {
  5271. Log($"{stepIndex + 1}-{processName}", $"鱼叉口宽参数,点数大于产品配置点数!", WarningEnum.High);
  5272. return stepIndex;
  5273. }
  5274. //走位计算
  5275. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5276. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5277. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5278. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + 2 * posIndex]);
  5279. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5280. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5281. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5282. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + 2 * posIndex + 1]);
  5283. //TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5284. // + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5285. // + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5286. // + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + 4 * posIndex + 2]);
  5287. //TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5288. // + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5289. // + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5290. // + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + 4 * posIndex + 3]);
  5291. break;
  5292. case PointTestType.鱼叉口间距:
  5293. IsOverDef = false;
  5294. TestCnt = testParam.PointCnt;
  5295. t = model.TestDefectPointsList.Where(q => q.PointCode == "鱼叉口间距").ToList();
  5296. if (testParam.AutoMark)
  5297. if (testParam.PointCnt > t.Count)
  5298. {
  5299. Log($"{stepIndex + 1}-{processName}", $"鱼叉口间距参数,点数大于产品配置点数!", WarningEnum.High);
  5300. return stepIndex;
  5301. }
  5302. //走位计算
  5303. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5304. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5305. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5306. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13] + 4 * posIndex]);
  5307. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5308. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5309. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5310. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13] + 4 * posIndex + 1]);
  5311. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5312. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5313. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5314. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5315. + 4 * posIndex + 2]);
  5316. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5317. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5318. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5319. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5320. + 4 * posIndex + 3]);
  5321. break;
  5322. case PointTestType.蜈蚣角长:
  5323. IsOverDef = false;
  5324. TestCnt = testParam.PointCnt;
  5325. t = model.TestDefectPointsList.Where(q => q.PointCode == "蜈蚣角长").ToList();
  5326. if (testParam.AutoMark)
  5327. if (testParam.PointCnt > t.Count)
  5328. {
  5329. Log($"{stepIndex + 1}-{processName}", $"蜈蚣角长参数,点数大于产品配置点数!", WarningEnum.High);
  5330. return stepIndex;
  5331. }
  5332. //走位计算
  5333. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5334. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5335. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5336. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5337. + this.CurrAdaqter[14] + 4 * posIndex]);
  5338. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5339. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5340. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5341. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5342. + this.CurrAdaqter[14] + 4 * posIndex + 1]);
  5343. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5344. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5345. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5346. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5347. + this.CurrAdaqter[14] + 4 * posIndex + 2]);
  5348. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5349. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5350. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5351. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5352. + this.CurrAdaqter[14] + 4 * posIndex + 3]);
  5353. break;
  5354. case PointTestType.蜈蚣角宽:
  5355. IsOverDef = true;
  5356. TestCnt = testParam.PointCnt;
  5357. t = model.TestDefectPointsList.Where(q => q.PointCode == "蜈蚣角宽").ToList();
  5358. if (testParam.AutoMark)
  5359. if (testParam.PointCnt > t.Count)
  5360. {
  5361. Log($"{stepIndex + 1}-{processName}", $"蜈蚣角宽参数,点数大于产品配置点数!", WarningEnum.High);
  5362. return stepIndex;
  5363. }
  5364. //走位计算
  5365. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5366. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5367. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5368. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5369. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + 2 * posIndex]);
  5370. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5371. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5372. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5373. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5374. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + 2 * posIndex + 1]);
  5375. break;
  5376. case PointTestType.分片间隔:
  5377. IsOverDef = false;
  5378. TestCnt = testParam.PointCnt;
  5379. t = model.TestDefectPointsList.Where(q => q.PointCode == "分片间隔").ToList();
  5380. if (testParam.AutoMark)
  5381. if (testParam.PointCnt > t.Count)
  5382. {
  5383. Log($"{stepIndex + 1}-{processName}", $"分片间隔参数,点数大于产品配置点数!", WarningEnum.High);
  5384. return stepIndex;
  5385. }
  5386. //走位计算
  5387. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5388. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5389. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5390. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5391. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + 4 * posIndex]);
  5392. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5393. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5394. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5395. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5396. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + 4 * posIndex + 1]);
  5397. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5398. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5399. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5400. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5401. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + 4 * posIndex + 2]);
  5402. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5403. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5404. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5405. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5406. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + 4 * posIndex + 3]);
  5407. break;
  5408. case PointTestType.焊点长:
  5409. IsOverDef = false;
  5410. TestCnt = testParam.PointCnt;
  5411. t = model.TestDefectPointsList.Where(q => q.PointCode == "焊点长").ToList();
  5412. if (testParam.AutoMark)
  5413. if (testParam.PointCnt > t.Count)
  5414. {
  5415. Log($"{stepIndex + 1}-{processName}", $"焊点长参数,点数大于产品配置点数!", WarningEnum.High);
  5416. return stepIndex;
  5417. }
  5418. //走位计算
  5419. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5420. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5421. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5422. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5423. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5424. + 4 * posIndex]);
  5425. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5426. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5427. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5428. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5429. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5430. + 4 * posIndex + 1]);
  5431. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5432. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5433. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5434. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5435. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5436. + 4 * posIndex + 2]);
  5437. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5438. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5439. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5440. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5441. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5442. + 4 * posIndex + 3]);
  5443. break;
  5444. case PointTestType.焊点宽:
  5445. IsOverDef = false;
  5446. TestCnt = testParam.PointCnt;
  5447. t = model.TestDefectPointsList.Where(q => q.PointCode == "焊点宽").ToList();
  5448. if (testParam.AutoMark)
  5449. if (testParam.PointCnt > t.Count)
  5450. {
  5451. Log($"{stepIndex + 1}-{processName}", $"焊点宽参数,点数大于产品配置点数!", WarningEnum.High);
  5452. return stepIndex;
  5453. }
  5454. //走位计算
  5455. //走位计算
  5456. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5457. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5458. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5459. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5460. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5461. + this.CurrAdaqter[18] + 4 * posIndex]);
  5462. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5463. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5464. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5465. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5466. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5467. + this.CurrAdaqter[18] + 4 * posIndex + 1]);
  5468. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5469. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5470. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5471. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5472. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5473. + this.CurrAdaqter[18] + 4 * posIndex + 2]);
  5474. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5475. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5476. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5477. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5478. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5479. + this.CurrAdaqter[18] + 4 * posIndex + 3]);
  5480. break;
  5481. case PointTestType.焊点间隔:
  5482. IsOverDef = false;
  5483. TestCnt = testParam.PointCnt;
  5484. t = model.TestDefectPointsList.Where(q => q.PointCode == "焊点间隔").ToList();
  5485. if (testParam.AutoMark)
  5486. if (testParam.PointCnt > t.Count)
  5487. {
  5488. Log($"{stepIndex + 1}-{processName}", $"焊点间隔参数,点数大于产品配置点数!", WarningEnum.High);
  5489. return stepIndex;
  5490. }
  5491. //走位计算
  5492. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5493. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5494. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5495. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5496. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5497. + this.CurrAdaqter[18] + this.CurrAdaqter[19] + 4 * posIndex]);
  5498. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5499. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5500. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5501. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5502. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5503. + this.CurrAdaqter[18] + this.CurrAdaqter[19] + 4 * posIndex + 1]);
  5504. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5505. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5506. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5507. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5508. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5509. + this.CurrAdaqter[18] + this.CurrAdaqter[19] + 4 * posIndex + 2]);
  5510. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5511. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5512. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5513. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5514. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5515. + this.CurrAdaqter[18] + this.CurrAdaqter[19] + 4 * posIndex + 3]);
  5516. break;
  5517. case PointTestType.SP2主栅宽度:
  5518. IsOverDef = false;
  5519. TestCnt = testParam.PointCnt;
  5520. t = model.TestDefectPointsList.Where(q => q.PointCode == "SP2主栅宽度").ToList();
  5521. if (testParam.AutoMark)
  5522. if (testParam.PointCnt > t.Count)
  5523. {
  5524. Log($"{stepIndex + 1}-{processName}", $"SP2主栅宽度参数,点数大于产品配置点数!", WarningEnum.High);
  5525. return stepIndex;
  5526. }
  5527. //走位计算
  5528. TestPosTagPPUValue[0] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5529. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5530. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5531. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5532. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5533. + this.CurrAdaqter[18] + this.CurrAdaqter[19] + this.CurrAdaqter[20] + 4 * posIndex]);
  5534. TestPosTagPPUValue[1] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5535. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5536. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5537. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5538. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5539. + this.CurrAdaqter[18] + this.CurrAdaqter[19] + this.CurrAdaqter[20] + 4 * posIndex + 1]);
  5540. TestPosTagPPUValue[2] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5541. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5542. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5543. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5544. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5545. + this.CurrAdaqter[18] + this.CurrAdaqter[19] + this.CurrAdaqter[20] + 4 * posIndex + 2]);
  5546. TestPosTagPPUValue[3] = double.Parse(TestPos[this.CurrAdaqter[0] * 4 + this.CurrAdaqter[1]
  5547. + this.CurrAdaqter[2] + this.CurrAdaqter[3] * 4 + this.CurrAdaqter[4] + this.CurrAdaqter[5]
  5548. + this.CurrAdaqter[6] + this.CurrAdaqter[7] + this.CurrAdaqter[8] + this.CurrAdaqter[9]
  5549. + this.CurrAdaqter[10] + this.CurrAdaqter[11] + this.CurrAdaqter[12] + this.CurrAdaqter[13]
  5550. + this.CurrAdaqter[14] + this.CurrAdaqter[15] + this.CurrAdaqter[16] + this.CurrAdaqter[17]
  5551. + this.CurrAdaqter[18] + this.CurrAdaqter[19] + this.CurrAdaqter[20] + 4 * posIndex + 3]);
  5552. break;
  5553. default:
  5554. Log($"{stepIndex + 1}-{processName}", $"参数不支持!", WarningEnum.High);
  5555. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"参数不支持!", 4, false));
  5556. return stepIndex;
  5557. }
  5558. }
  5559. //PT检测需要两点
  5560. for (int i = 0; i < 2; i++)
  5561. {
  5562. //轴运动
  5563. for (int j = 0; j < 2; j++)
  5564. {
  5565. if (axisDev.CheckDone(PAxisIndexList[j], 60) != 0)
  5566. {
  5567. Log($"{stepIndex + 1}-{processName}", $"轴{PAxisIndexList[j]}到位失败!", WarningEnum.High);
  5568. return stepIndex;
  5569. }
  5570. VelocityCurveParams vel = new VelocityCurveParams(testParam.Acc, testParam.Dec, testParam.VelLow, testParam.VelHigh, MotionST, GetMMtoPlus((AxisName)PAxisIndexList[i]));
  5571. int iret = 0;
  5572. iret = axisDev.MoveAbsValue(PAxisIndexList[j], vel, TestPosTagPPUValue[j + i *2]);
  5573. if (iret != 0)
  5574. {
  5575. Log($"{stepIndex + 1}-{processName}", $"轴{PAxisIndexList[j]}运动失败!", WarningEnum.High);
  5576. return stepIndex;
  5577. }
  5578. }
  5579. //多轴同时运行后强制等待各轴完成
  5580. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  5581. if (!WaitAxisDone(PAxisIndexList))
  5582. {
  5583. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  5584. return stepIndex;
  5585. }
  5586. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  5587. Thread.Sleep(testParam.WaitTime);
  5588. camDevFront.SetExposure(testParam.ExposureTime);
  5589. camDevFront.SetGain(testParam.Gain);
  5590. //自动聚焦?
  5591. if ((this.CurrPoinntCount == 0) && (IsAutoFocus)&& (i == 0))//第一次拍照才聚焦
  5592. {
  5593. Log($"{stepIndex + 1}-{processName}", $"自动聚焦...");
  5594. if (!AutoFocus(FocusStep, DirStep, DirWaitTime, FocusTimeOut))
  5595. {
  5596. Log($"{stepIndex + 1}-{processName}", $"自动聚焦失败!", WarningEnum.High);
  5597. return stepIndex;
  5598. }
  5599. Log($"{stepIndex + 1}-{processName}", $"自动聚焦完成");
  5600. }
  5601. else if (testParam.AutoFocus)//每次都聚焦
  5602. {
  5603. Log($"{stepIndex + 1}-{processName}", $"拍照前自动聚焦...");
  5604. if (!AutoFocus(testParam.FocusStep, testParam.DirStep, testParam.WaitDoneTime, testParam.TimeOut))
  5605. {
  5606. Log($"{stepIndex + 1}-{processName}", $"拍照前自动聚焦失败!", WarningEnum.High);
  5607. return stepIndex;
  5608. }
  5609. Log($"{stepIndex + 1}-{processName}", $"拍照前自动聚焦完成");
  5610. }
  5611. //拍照
  5612. Log($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  5613. DateTime test_dt = DateTime.Now;
  5614. camDevFront.ClearImageQueue();
  5615. Acquisition test_acq = camDevFront.Snap(1, 5000);
  5616. if (test_acq.GrabStatus != "GrabPass")
  5617. {
  5618. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片失败!", WarningEnum.High);
  5619. return stepIndex;
  5620. }
  5621. Log($"{stepIndex + 1}-{processName}", $"前部相机采集照片完成[" + (DateTime.Now - test_dt).Milliseconds.ToString() + "ms]");
  5622. //显示
  5623. OnAutoRuning(new RunEventArgs(0, test_acq.Image));
  5624. //----处理队列
  5625. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  5626. test_acq.Image.Clone(),
  5627. GetAxisPosValueMM((int)AxisName.Axis0),
  5628. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  5629. Log($"{stepIndex + 1}-{processName}", $"添加尺寸图像队列," +
  5630. $"X:{GetAxisPosValueMM((int)AxisName.Axis0)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  5631. $"数量: {scannerCBmpQueue.Count}");
  5632. //处理
  5633. if (!PointTestDef(stepIndex, processName, testParam.EngineName, gbxBmpPath, false, model, testParam, IsOverDef))
  5634. {
  5635. Log($"{stepIndex + 1}-{processName}", $"单点测试图像,比对任务失败!", WarningEnum.High);
  5636. return stepIndex;
  5637. }
  5638. //需要二次点位的在循环,否则直接跳出
  5639. if (!IsOverDef)
  5640. IsOverDef = true;
  5641. else
  5642. break;
  5643. }
  5644. #endregion
  5645. break;
  5646. case "SizeAndDefect":
  5647. #region 缺陷
  5648. SizeDefectProp defectParam = JsonConvert.DeserializeObject<SizeDefectProp>(jsonParams);
  5649. if (confMgr.SysConfigParams.DisableBackCam)
  5650. {
  5651. Log($"{stepIndex + 1}-{processName}", $"设备禁用,忽略此步骤!");
  5652. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"设备禁用,忽略此步骤!", 0, true));
  5653. break;
  5654. }
  5655. if (!DefectEnable)
  5656. {
  5657. Log($"{stepIndex + 1}-{processName}", $"缺陷检测功能禁用,忽略此步骤!");
  5658. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"缺陷检测功能禁用,忽略此步骤!", 0, true));
  5659. break;
  5660. }
  5661. //对应运动轴
  5662. List<int> DAxisIndexList = new List<int>();
  5663. DAxisIndexList.Add(AxisX2);
  5664. DAxisIndexList.Add(AxisY);
  5665. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"比对和缺陷检测开始...", 1, true));
  5666. //获取首点和长宽
  5667. if (this.CurrPoinntCount == 0)
  5668. {
  5669. //添加打印信息
  5670. AddDefectPrintInfo(defectParam);
  5671. OnAutoRuning(new RunEventArgs(liStatocStepIndex, "比对和缺陷检测开始...", null, 0, 0, 0, 1, true));
  5672. double Pdt_Width = 0;
  5673. double Pdt_Height = 0;
  5674. //根据mark寻找trg
  5675. //判断有无tag
  5676. if (order.SizeTagDataList == null)
  5677. {
  5678. Log($"{stepIndex + 1}-{processName}", $"Mark数据提供者Tag为空!", WarningEnum.High);
  5679. return stepIndex;
  5680. }
  5681. //tag
  5682. string LeftPosTag = "B_Pos";
  5683. //用最新的last
  5684. var LeftPosTagObj = order.SizeTagDataList.LastOrDefault(m => m.SizeTag == LeftPosTag);
  5685. if (LeftPosTagObj == null)
  5686. {
  5687. Log($"{stepIndex + 1}-{processName}", $"未找到自动获取的左上角和产品大小数据!", WarningEnum.High);
  5688. return stepIndex;
  5689. }
  5690. string[] PosAndSize = LeftPosTagObj.posePT.Split(',');
  5691. if (PosAndSize.Length < 6)
  5692. {
  5693. Log($"{stepIndex + 1}-{processName}",
  5694. $"缺陷检测首点对应消费索引:{this.CurrPoinntCount * 2},Axis数量:{2} 超出postPT:{LeftPosTagObj.posePT} 范围!", WarningEnum.High);
  5695. return stepIndex;
  5696. }
  5697. //获取首点,计算步进
  5698. //Left_X = double.Parse(PosAndSize[0]) + confMgr.SysConfigParams.DefectCamViewX; //需要偏移
  5699. //Left_Y = double.Parse(PosAndSize[1]);
  5700. Left_X = double.Parse(PosAndSize[4]);
  5701. Left_Y = double.Parse(PosAndSize[5]);
  5702. Pdt_Width = double.Parse(PosAndSize[2]);
  5703. Pdt_Height = double.Parse(PosAndSize[3]);
  5704. //X_For = (int)(Pdt_Width / confMgr.SysConfigParams.DefectCamViewX) + 1;
  5705. //Y_For = (int)(Pdt_Height / confMgr.SysConfigParams.DefectCamViewY) + 1;
  5706. //左上角加入视野大小10%的补偿
  5707. double temp_dis = confMgr.SysConfigParams.DefectCamViewX * confMgr.SysConfigParams.X_per;
  5708. Left_X = double.Parse(PosAndSize[4]) - temp_dis;
  5709. temp_dis = confMgr.SysConfigParams.DefectCamViewY * confMgr.SysConfigParams.Y_per;
  5710. Left_Y = double.Parse(PosAndSize[5]) + temp_dis;
  5711. //double temp_dis = ((X_For * confMgr.SysConfigParams.DefectCamViewX - Pdt_Width) / 2);
  5712. //if (temp_dis < (confMgr.SysConfigParams.DefectCamViewX / 5))
  5713. //{
  5714. // X_For = X_For + 1;
  5715. // temp_dis = ((X_For * confMgr.SysConfigParams.DefectCamViewX - Pdt_Width) / 2);
  5716. //}
  5717. //Left_X = double.Parse(PosAndSize[4]) - temp_dis;
  5718. //temp_dis = ((Y_For * confMgr.SysConfigParams.DefectCamViewY - Pdt_Height) / 2);
  5719. //if (temp_dis < (confMgr.SysConfigParams.DefectCamViewY / 5))
  5720. //{
  5721. // Y_For++;
  5722. // temp_dis = ((Y_For * confMgr.SysConfigParams.DefectCamViewY - Pdt_Height) / 2);
  5723. //}
  5724. //Left_Y = double.Parse(PosAndSize[5]) + temp_dis;
  5725. if ((Pdt_Width + (confMgr.SysConfigParams.DefectCamViewX * confMgr.SysConfigParams.X_per))
  5726. % confMgr.SysConfigParams.DefectCamViewX > 0)
  5727. X_For = (int)((Pdt_Width + (confMgr.SysConfigParams.DefectCamViewX * confMgr.SysConfigParams.X_per) )/ confMgr.SysConfigParams.DefectCamViewX) + 1;
  5728. else
  5729. X_For = (int)((Pdt_Width + (confMgr.SysConfigParams.DefectCamViewX * confMgr.SysConfigParams.X_per)) / confMgr.SysConfigParams.DefectCamViewX);
  5730. if ((Pdt_Height + (confMgr.SysConfigParams.DefectCamViewY * confMgr.SysConfigParams.Y_per))
  5731. % confMgr.SysConfigParams.DefectCamViewY > 0)
  5732. Y_For = (int)((Pdt_Height + (confMgr.SysConfigParams.DefectCamViewY * confMgr.SysConfigParams.Y_per)) / confMgr.SysConfigParams.DefectCamViewY) + 1;
  5733. else
  5734. Y_For = (int)((Pdt_Height + (confMgr.SysConfigParams.DefectCamViewY * confMgr.SysConfigParams.Y_per)) / confMgr.SysConfigParams.DefectCamViewY);
  5735. //判断是否使用手动
  5736. if(!defectParam.AutoLeft)
  5737. {
  5738. if (defectParam.LeftPoints.Count > 0)
  5739. {
  5740. Left_X = defectParam.LeftPoints[0].X;
  5741. Left_Y = defectParam.LeftPoints[0].Y;
  5742. }
  5743. else
  5744. {
  5745. Log($"{stepIndex + 1}-{processName}", $"设置左上角为空{defectParam.LeftPoints[0]}!", WarningEnum.High);
  5746. return stepIndex;
  5747. }
  5748. }
  5749. if (!defectParam.AutoStep)
  5750. {
  5751. X_For = defectParam.Xstep;
  5752. Y_For = defectParam.Ystep;
  5753. }
  5754. X_For_Index = 0;
  5755. Y_For_Index = 0;
  5756. ////////////////////
  5757. //X_For = 6;
  5758. //Y_For = 7;
  5759. }
  5760. TestCnt = Y_For * X_For;
  5761. //走位计算
  5762. double[] PosTagPPUValue = new double[DAxisIndexList.Count];
  5763. PosTagPPUValue[0] = Left_X + X_For_Index * confMgr.SysConfigParams.DefectCamViewX;
  5764. PosTagPPUValue[1] = Left_Y - Y_For_Index * confMgr.SysConfigParams.DefectCamViewY;
  5765. //轴运动
  5766. for (int i = 0; i < PosTagPPUValue.Length; i++)
  5767. {
  5768. if (axisDev.CheckDone(DAxisIndexList[i], 60) != 0)
  5769. {
  5770. Log($"{stepIndex + 1}-{processName}", $"轴{DAxisIndexList[i]}到位失败!", WarningEnum.High);
  5771. return stepIndex;
  5772. }
  5773. VelocityCurveParams vel = new VelocityCurveParams(defectParam.Acc, defectParam.Dec, defectParam.VelLow, defectParam.VelHigh, MotionST, GetMMtoPlus((AxisName)DAxisIndexList[i]));
  5774. int iret = 0;
  5775. iret = axisDev.MoveAbsValue(DAxisIndexList[i], vel, PosTagPPUValue[i]);
  5776. if (iret != 0)
  5777. {
  5778. Log($"{stepIndex + 1}-{processName}", $"轴{DAxisIndexList[i]}运动失败!", WarningEnum.High);
  5779. return stepIndex;
  5780. }
  5781. }
  5782. //if (sizeTagObj.ConsumeStepIndex == null)
  5783. // sizeTagObj.ConsumeStepIndex = "";
  5784. //sizeTagObj.ConsumeStepIndex += $"{stepIndex + 1}-{this.CurrPoinntCount}, ";//消费工序ID
  5785. //多轴同时运行后强制等待各轴完成
  5786. Log($"{stepIndex + 1}-{processName}", $"等待轴组运行完成...");
  5787. if (!WaitAxisDone(DAxisIndexList))
  5788. {
  5789. Log($"{stepIndex + 1}-{processName}", $"轴到位失败!", WarningEnum.High);
  5790. return stepIndex;
  5791. }
  5792. Log($"{stepIndex + 1}-{processName}", $"轴组运行完成");
  5793. Thread.Sleep(defectParam.WaitTime);
  5794. //拍照
  5795. Log($"{stepIndex + 1}-{processName}", $"相机开始采集照片...");
  5796. CamDevBack.SetExposure(defectParam.ExposureTime);
  5797. CamDevBack.SetGain(defectParam.Gain);
  5798. DateTime def_dt = DateTime.Now;
  5799. CamDevBack.ClearImageQueue();
  5800. Acquisition def_acq = CamDevBack.Snap(1, 5000);
  5801. if (def_acq.GrabStatus != "GrabPass")
  5802. {
  5803. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片失败!", WarningEnum.High);
  5804. return stepIndex;
  5805. }
  5806. Log($"{stepIndex + 1}-{processName}", $"后部相机采集照片完成[" + (DateTime.Now - def_dt).Milliseconds.ToString() + "ms]");
  5807. //显示
  5808. OnAutoRuning(new RunEventArgs(1, def_acq.Image));
  5809. //图纸
  5810. attachmentFile = model.AttachmentList.FirstOrDefault(x => x.Type == 0);
  5811. Log($"{stepIndex + 1}-{processName}", $"比对图像,{model.AttachmentList.Count}|{(attachmentFile == null ? "null" : attachmentFile.NameTimestamp + attachmentFile.ExtendName)}");
  5812. if (attachmentFile != null)
  5813. {
  5814. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  5815. if (!File.Exists(gbxBmpPath + attachmentFile.ExtendName))
  5816. gbxBmpPath = "";
  5817. }
  5818. if (gbxBmpPath == "")
  5819. {
  5820. Log($"{stepIndex + 1}-{processName}", $"比对图像,图纸不存在!", WarningEnum.High);
  5821. return stepIndex;
  5822. }
  5823. //----缺陷队列
  5824. if (defectParam.OpenDefect)
  5825. {
  5826. var mat = CamDev.HImageToMat(def_acq.Image);
  5827. scannerGBmpQueue.Enqueue(new scannerGBmpLoc(mat,
  5828. GetAxisPosValueMM((int)AxisName.Axis1),
  5829. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  5830. Log($"{stepIndex + 1}-{processName}", $"缺陷图像队列数量: {scannerGBmpQueue.Count}");
  5831. if(!DefectPicture(stepIndex, processName, defectParam, gbxBmpPath, model, model.StepInfo.Name))
  5832. {
  5833. Log($"{stepIndex + 1}-{processName}", $"缺陷处理,缺陷任务失败!", WarningEnum.High);
  5834. return stepIndex;
  5835. }
  5836. }
  5837. if (defectParam.OpenSize)
  5838. {
  5839. scannerCBmpQueue.Enqueue(new scannerCBmpLoc(
  5840. def_acq.Image.Clone(),
  5841. GetAxisPosValueMM((int)AxisName.Axis1),
  5842. GetAxisPosValueMM((int)AxisName.Axis2)));//Dequeue
  5843. Log($"{stepIndex + 1}-{processName}", $"比对图像队列," +
  5844. $"X:{GetAxisPosValueMM((int)AxisName.Axis1)},y:{GetAxisPosValueMM((int)AxisName.Axis2)}," +
  5845. $"数量: {scannerCBmpQueue.Count}");
  5846. //比对处理
  5847. if(!SizeComp(stepIndex, processName, defectParam.EngineName, gbxBmpPath, model.StepInfo.Name, defectParam.AsynRun))
  5848. {
  5849. Log($"{stepIndex + 1}-{processName}", $"比对图像,比对任务失败!", WarningEnum.High);
  5850. return stepIndex;
  5851. }
  5852. }
  5853. //计算下一步
  5854. if (Y_For_Index % 2 == 0)
  5855. {
  5856. X_For_Index++;
  5857. if (X_For_Index >= X_For)
  5858. {
  5859. Y_For_Index++;
  5860. X_For_Index--;
  5861. }
  5862. }
  5863. else
  5864. {
  5865. X_For_Index--;
  5866. if (X_For_Index < 0)
  5867. {
  5868. Y_For_Index++;
  5869. X_For_Index++;
  5870. }
  5871. }
  5872. if (Y_For_Index >= Y_For)
  5873. {
  5874. Y_For_Index = 0;
  5875. X_For_Index = 0;
  5876. }
  5877. #endregion
  5878. break;
  5879. case "For":
  5880. #region 循环
  5881. long UniqueId = processParam.Value<long>("UniqueId");
  5882. int GotoStepIndex = processParam.Value<int>("GotoStepIndex");//1-n
  5883. int LimitNum = processParam.Value<int>("LimitNum");//1-n
  5884. bool Reset = processParam.Value<bool>("Reset");
  5885. if (GotoStepIndex - 1 == stepIndex)
  5886. {
  5887. Log($"{stepIndex + 1}-{processName}", $"For死循环!!!", WarningEnum.High);
  5888. return stepIndex;
  5889. }
  5890. if (!forLib.dicData.ContainsKey(UniqueId))
  5891. forLib.dicData.Add(UniqueId, 0);
  5892. //
  5893. int Num = forLib.dicData[UniqueId];
  5894. Num++;
  5895. if (Num <= LimitNum)
  5896. {
  5897. if (Num == LimitNum)
  5898. {
  5899. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num}/{LimitNum}]次,循环完成"));
  5900. Log($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次,循环完成。");
  5901. }
  5902. else
  5903. {
  5904. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[{Num}/{LimitNum}]次"));
  5905. Log($"{stepIndex + 1}-{processName}", $"第[{Num}/{LimitNum}]次跳转到步骤[{GotoStepIndex}]...");
  5906. stepIndex = GotoStepIndex - 2;
  5907. }
  5908. forLib.dicData[UniqueId] = Num;
  5909. }
  5910. else
  5911. {
  5912. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"已失效不执行"));
  5913. Log($"{stepIndex + 1}-{processName}", $"本循环已失效不执行!");
  5914. }
  5915. //达到limit重置0
  5916. if (forLib.dicData[UniqueId] >= LimitNum && Reset)
  5917. {
  5918. forLib.dicData[UniqueId] = 0;
  5919. OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"第[0/{LimitNum}]次"));
  5920. Log($"{stepIndex + 1}-{processName}", $"计数器已重置。");
  5921. }
  5922. #endregion
  5923. break;
  5924. default:
  5925. Log($"{stepIndex + 1}-{processName}", $"未知新工序:{processInfo.ProcessCode}", WarningEnum.High);
  5926. return stepIndex;
  5927. }
  5928. #endregion
  5929. }
  5930. }
  5931. else
  5932. {
  5933. if (IsNewStep)
  5934. {
  5935. OnAutoRuning(new RunEventArgs(stepIndex, $"未启用,忽略此步骤!", 0, processInfo.ProcessCode == "SizeAndDefect"));
  5936. }
  5937. }
  5938. //============结束,判断是否自动下料
  5939. if (!IsNewStep)
  5940. {
  5941. #region 老流程结束判断
  5942. if (stepIndex == processList.Count - 1)
  5943. {
  5944. Log("下料", "产品测试完成,移动到下料位");
  5945. bool ret = GotoLoadPos();
  5946. if (!ret)
  5947. {
  5948. Log("下料", "系统电机复位失败", WarningEnum.High);
  5949. }
  5950. if (!RunQG(false))
  5951. {
  5952. Log("下料", "系统IO复位失败", WarningEnum.High);
  5953. }
  5954. Log("结果", "产品测试完成,等待测试结果...");
  5955. //等待缺陷图显示完成
  5956. while (defectBmpNum != defectBmpNumResult)
  5957. Thread.Sleep(100);
  5958. //判断是否合格
  5959. DefectCodeEnum defectCode;
  5960. string defectNames = "";
  5961. {
  5962. #region 结果判断
  5963. Log("结果", "结果判断");
  5964. int itemDefectCount;
  5965. bool isGetQua = false;
  5966. for (int enumcnt = 0; enumcnt < 14; enumcnt++)
  5967. {
  5968. isGetQua = false;
  5969. //判断是否是过滤项
  5970. if (model.QualifiedCriterionList != null && model.QualifiedCriterionList.Count > 0)
  5971. {
  5972. foreach (var item in model.QualifiedCriterionList)
  5973. {
  5974. try
  5975. {
  5976. defectCode = EnumExtension.Convert2Enum<DefectCodeEnum>(item.DefectCode);
  5977. //是过滤
  5978. if (defectCode == (DefectCodeEnum)enumcnt)
  5979. {
  5980. isGetQua = true;
  5981. itemDefectCount = getDefectCountFromCode(order, defectCode);
  5982. if (item.MaxDefectCount > -1 && itemDefectCount > item.MaxDefectCount)
  5983. {
  5984. order.Qualified = false;
  5985. defectNames += $"{EnumExtension.GetEnumDescription(defectCode)}({itemDefectCount}),";
  5986. }
  5987. }
  5988. }
  5989. catch { }
  5990. }
  5991. }
  5992. if (!isGetQua)
  5993. {
  5994. itemDefectCount = getDefectCountFromCode(order, (DefectCodeEnum)enumcnt);
  5995. if (itemDefectCount > 0)
  5996. {
  5997. order.Qualified = false;
  5998. defectNames += $"{EnumExtension.GetEnumDescription((DefectCodeEnum)enumcnt)}({itemDefectCount}),";
  5999. }
  6000. }
  6001. }
  6002. #endregion
  6003. }
  6004. stopWatch.Stop();
  6005. long timeLen = stopWatch.ElapsedMilliseconds / 1000;
  6006. OnAutoRuning(new RunEventArgs(4, defectNames == "", AllDefectCount, defectNames));
  6007. OnAutoRuning(new RunEventArgs(timeLen));
  6008. //界面显示
  6009. order.TimeLen = timeLen;
  6010. order.DefectCount = AllDefectCount;
  6011. order.Succeed = true;
  6012. order.ModifyUserCode = order.CreateUserCode = userMgr.LoginUser.Code;
  6013. order.Abnormalities = "";//无异常
  6014. order.RepairCode = "";//无修复人员
  6015. //如SN检测已存在,先删除
  6016. var oldSNOrder = OrderService.GetFirst(m => m.SN == order.SN);
  6017. if (oldSNOrder != null)
  6018. {
  6019. Log("删除记录", $"删除上一重复SN检测记录:SN={oldSNOrder.SN}, Date={oldSNOrder.CreateTime}");
  6020. OrderService.DelNav(oldSNOrder);
  6021. }
  6022. if (!OrderService.InsertNav(order))//导航插入
  6023. Log("保存失败", $"保存生产记录失败!", WarningEnum.Low);
  6024. //更新本批次检测数量
  6025. if (!string.IsNullOrWhiteSpace(model.BatchId))
  6026. {
  6027. var expOrder = Expressionable.Create<Order>()
  6028. .And(m => m.ProductId == model.Id)
  6029. .And(m => m.BatchId == model.BatchId)
  6030. .ToExpression();//注意 这一句 不能少
  6031. CurrProductModel.CompleteCount = OrderService.Count(expOrder);
  6032. }
  6033. //以主键为条件更新CompleteCount单列值
  6034. PdtService.Update(it => new Product() { CompleteCount = CurrProductModel.CompleteCount }, it => it.Id == CurrProductModel.Id);
  6035. //记录日产量
  6036. if(confMgr.SetDailyOutputAdd(out DailyOutput))
  6037. {
  6038. OnAutoRuning(new RunEventArgs(timeLen, DailyOutput));
  6039. SendDailyOutput();
  6040. }
  6041. Log("完成", $"用时 {order.TimeLen} 秒");
  6042. _isAuto = false;
  6043. OnAutoRuning(new RunEventArgs(_isAuto));
  6044. //GotoReadyPosAndIO();
  6045. statusMgr.ClearWarning();
  6046. LedReady();
  6047. statusMgr.GotoNormalStandby();
  6048. SendStatus();
  6049. CurrPoinntCount = 0;
  6050. CurrProcessIndex = -1;
  6051. #region MES
  6052. //MES上传
  6053. if (confMgr.SysConfigParams.EnableHttp)
  6054. {
  6055. string messtr = GetMesString(confMgr.SysConfigParams.HttpTempPath, model, false);
  6056. Log("MES上传", $"Url:{confMgr.SysConfigParams.HttpUrl}, Date={messtr}");
  6057. string rel = "";
  6058. try
  6059. {
  6060. rel = HttpApi.Post(confMgr.SysConfigParams.HttpUrl, HttpApi.HttpContentType.application_json, messtr);
  6061. Log("MES反馈", $"return:{rel}");
  6062. }
  6063. catch (Exception e)
  6064. {
  6065. Log("MES上传失败", $"失败原因:{e.Message}");
  6066. }
  6067. if (!string.IsNullOrEmpty(rel))
  6068. {
  6069. try
  6070. {
  6071. JObject jo = (JObject)JsonConvert.DeserializeObject(rel);
  6072. if (jo != null)
  6073. {
  6074. if (jo.ContainsKey(confMgr.SysConfigParams.HttpReturnKey) && jo[confMgr.SysConfigParams.HttpReturnKey] != null)
  6075. {
  6076. if (jo[confMgr.SysConfigParams.HttpReturnKey].ToString() == confMgr.SysConfigParams.HttpReturnValue)
  6077. Log("MES上传", $"上传数据成功:{rel}");
  6078. else
  6079. Log("MES上传", $"上传数据失败:{rel}", WarningEnum.Low);
  6080. }
  6081. else
  6082. Log("MES上传", $"上传数据无返回结果:{rel}", WarningEnum.Low);
  6083. }
  6084. else
  6085. {
  6086. Log("MES上传", $"上传数据无反应:{rel}", WarningEnum.Low);
  6087. }
  6088. }
  6089. catch (Exception e)
  6090. {
  6091. Log("MES反馈失败", $"失败原因:{e.Message}", WarningEnum.Low);
  6092. }
  6093. }
  6094. }
  6095. #endregion
  6096. #region 打印
  6097. if (confMgr.SysConfigParams.EnableLabelPrint)
  6098. {
  6099. Log("标签打印", $"打印机:{confMgr.SysConfigParams.LabelPrinterName}, 模板路径={confMgr.SysConfigParams.LabelTempPath}");
  6100. ret = PrintFileData(PrinterType.Label, confMgr.SysConfigParams.LabelPrinterName,
  6101. confMgr.SysConfigParams.LabelTempPath, confMgr.SysConfigParams.LabelData, model);
  6102. if (ret)
  6103. Log("标签打印", $"打印成功:{confMgr.SysConfigParams.LabelData}");
  6104. else
  6105. Log("标签打印", $"打印失败:打印机={confMgr.SysConfigParams.LabelPrinterName}, 模板路径={confMgr.SysConfigParams.LabelTempPath}, 打印数据={confMgr.SysConfigParams.LabelData}", WarningEnum.Low);
  6106. }
  6107. if (confMgr.SysConfigParams.EnableExcelPrint)
  6108. {
  6109. Log("Excel打印", $"打印机:{confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={confMgr.SysConfigParams.ExcelTempPath}");
  6110. ret = PrintFileData(PrinterType.Excel, confMgr.SysConfigParams.ExcelPrinterName,
  6111. confMgr.SysConfigParams.ExcelTempPath, confMgr.SysConfigParams.ExcelData, model);
  6112. if (ret)
  6113. Log("Excel打印", $"打印成功:{confMgr.SysConfigParams.ExcelData}");
  6114. else
  6115. Log("Excel打印", $"打印失败:打印机={confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={confMgr.SysConfigParams.ExcelTempPath}, 打印数据={confMgr.SysConfigParams.ExcelData}", WarningEnum.Low);
  6116. }
  6117. #endregion
  6118. return -1;
  6119. }
  6120. else //继续
  6121. {
  6122. return ++stepIndex;
  6123. }
  6124. #endregion
  6125. }
  6126. else
  6127. {
  6128. #region 新流程结束判断
  6129. this.CurrPoinntCount++;
  6130. if ((stepIndex == processList.Count - 1)&& (this.CurrPoinntCount >= TestCnt))
  6131. {
  6132. Log("下料", "产品测试完成,移动到下料位");
  6133. bool ret = GotoLoadPos();
  6134. if (!ret)
  6135. {
  6136. Log("下料", "系统电机复位失败", WarningEnum.High);
  6137. }
  6138. if (!RunQG(false))
  6139. {
  6140. Log("下料", "系统IO复位失败", WarningEnum.High);
  6141. }
  6142. Log("结果", "产品测试完成,等待测试结果...");
  6143. //等待比对显示完成
  6144. while (compBmpNum != compBmpIndex)
  6145. Thread.Sleep(100);
  6146. //等待缺陷图显示完成
  6147. while (defectBmpNum != defectBmpNumResult)
  6148. Thread.Sleep(100);
  6149. //判断是否合格
  6150. DefectCodeEnum defectCode;
  6151. string defectNames = "";
  6152. if (model.QualifiedCriterionList != null && model.QualifiedCriterionList.Count > 0)
  6153. {
  6154. int itemDefectCount;
  6155. foreach (var item in model.QualifiedCriterionList)
  6156. {
  6157. try
  6158. {
  6159. defectCode = EnumExtension.Convert2Enum<DefectCodeEnum>(item.DefectCode);
  6160. itemDefectCount = getDefectCountFromCode(order, defectCode);
  6161. if (item.MaxDefectCount > -1 && itemDefectCount > item.MaxDefectCount)
  6162. {
  6163. order.Qualified = false;
  6164. defectNames += $"{EnumExtension.GetEnumDescription(defectCode)}({itemDefectCount}),";
  6165. }
  6166. }
  6167. catch
  6168. { }
  6169. }
  6170. }
  6171. else
  6172. {
  6173. Log("结果", "默认判断");
  6174. int itemDefectCount;
  6175. for (int enumcnt = 0; enumcnt < 14; enumcnt++)
  6176. {
  6177. try
  6178. {
  6179. itemDefectCount = getDefectCountFromCode(order, (DefectCodeEnum)enumcnt);
  6180. if (itemDefectCount > 0)
  6181. {
  6182. order.Qualified = false;
  6183. defectNames += $"{EnumExtension.GetEnumDescription((DefectCodeEnum)enumcnt)}({itemDefectCount}),";
  6184. }
  6185. }
  6186. catch
  6187. { }
  6188. }
  6189. }
  6190. //移除最后的,
  6191. if(defectNames.Length>0)
  6192. {
  6193. defectNames = defectNames.Remove(defectNames.Length - 1);
  6194. }
  6195. stopWatch.Stop();
  6196. long timeLen = stopWatch.ElapsedMilliseconds / 1000;
  6197. //OnAutoRuning(new RunEventArgs(4, defectNames == "", AllDefectCount, defectNames));
  6198. OnAutoRuning(new RunEventArgs(stepIndex, $"缺陷检测全部完成:{defectNames}",
  6199. new List<double>(), 1, 0, AllDefectCount, defectNames == ""?2:3, true));
  6200. OnAutoRuning(new RunEventArgs(timeLen));
  6201. //界面显示
  6202. order.TimeLen = timeLen;
  6203. order.DefectCount = AllDefectCount;
  6204. order.Succeed = true;
  6205. order.ModifyUserCode = order.CreateUserCode = userMgr.LoginUser.Code;
  6206. order.Abnormalities = "";//无异常
  6207. order.RepairCode = "";//无修复人员
  6208. //如SN检测已存在,先删除
  6209. var oldSNOrder = OrderService.GetFirst(m => m.SN == order.SN);
  6210. if (oldSNOrder != null)
  6211. {
  6212. Log("删除记录", $"删除上一重复SN检测记录:SN={oldSNOrder.SN}, Date={oldSNOrder.CreateTime}");
  6213. OrderService.DelNav(oldSNOrder);
  6214. }
  6215. if (!OrderService.InsertNav(order))//导航插入
  6216. Log("保存失败", $"保存生产记录失败!", WarningEnum.Low);
  6217. //更新本批次检测数量
  6218. if (!string.IsNullOrWhiteSpace(model.BatchId))
  6219. {
  6220. var expOrder = Expressionable.Create<Order>()
  6221. .And(m => m.ProductId == model.Id)
  6222. .And(m => m.BatchId == model.BatchId)
  6223. .ToExpression();//注意 这一句 不能少
  6224. CurrProductModel.CompleteCount = OrderService.Count(expOrder);
  6225. }
  6226. //以主键为条件更新CompleteCount单列值
  6227. PdtService.Update(it => new Product() { CompleteCount = CurrProductModel.CompleteCount }, it => it.Id == CurrProductModel.Id);
  6228. //记录日产量
  6229. if (confMgr.SetDailyOutputAdd(out DailyOutput))
  6230. {
  6231. OnAutoRuning(new RunEventArgs(timeLen, DailyOutput));
  6232. SendDailyOutput();
  6233. }
  6234. Log("完成", $"用时 {order.TimeLen} 秒");
  6235. _isAuto = false;
  6236. OnAutoRuning(new RunEventArgs(_isAuto));
  6237. //GotoReadyPosAndIO();
  6238. statusMgr.ClearWarning();
  6239. LedReady();
  6240. statusMgr.GotoNormalStandby();
  6241. SendStatus();
  6242. CurrStepResult = 0;
  6243. CurrPoinntCount = 0;
  6244. CurrProcessIndex = -1;
  6245. #region MES
  6246. //MES上传
  6247. if (confMgr.SysConfigParams.EnableHttp)
  6248. {
  6249. string messtr = GetMesString(confMgr.SysConfigParams.HttpTempPath, model, true);
  6250. Log("MES上传", $"Url:{confMgr.SysConfigParams.HttpUrl}, Date={messtr}");
  6251. string rel = "";
  6252. try
  6253. {
  6254. rel = HttpApi.Post(confMgr.SysConfigParams.HttpUrl, HttpApi.HttpContentType.application_json, messtr);
  6255. Log("MES反馈", $"return:{rel}");
  6256. }
  6257. catch (Exception e)
  6258. {
  6259. Log("MES上传失败", $"失败原因:{e.Message}");
  6260. }
  6261. if (!string.IsNullOrEmpty(rel))
  6262. {
  6263. try
  6264. {
  6265. JObject jo = (JObject)JsonConvert.DeserializeObject(rel);
  6266. if (jo != null)
  6267. {
  6268. if (jo.ContainsKey(confMgr.SysConfigParams.HttpReturnKey) && jo[confMgr.SysConfigParams.HttpReturnKey] != null)
  6269. {
  6270. if(jo[confMgr.SysConfigParams.HttpReturnKey].ToString() == confMgr.SysConfigParams.HttpReturnValue)
  6271. Log("MES上传", $"上传数据成功:{rel}");
  6272. else
  6273. Log("MES上传", $"上传数据失败:{rel}", WarningEnum.Low);
  6274. }
  6275. else
  6276. Log("MES上传", $"上传数据无返回结果:{rel}", WarningEnum.Low);
  6277. }
  6278. else
  6279. {
  6280. Log("MES上传", $"上传数据无反应:{rel}", WarningEnum.Low);
  6281. }
  6282. }
  6283. catch (Exception e)
  6284. {
  6285. Log("MES反馈失败", $"失败原因:{e.Message}", WarningEnum.Low);
  6286. }
  6287. }
  6288. }
  6289. #endregion
  6290. #region 打印
  6291. if (model.EnableLabelPrint)
  6292. {
  6293. Log("标签打印", $"打印机:{confMgr.SysConfigParams.LabelPrinterName}, 模板路径={model.LabelTempPath}");
  6294. ret = PrintFileData(PrinterType.Label, confMgr.SysConfigParams.LabelPrinterName,
  6295. model.LabelTempPath, CurrPrintInfos, model);
  6296. if(ret)
  6297. Log("标签打印", $"打印成功:{CurrPrintInfos}");
  6298. else
  6299. Log("标签打印", $"打印失败:打印机={confMgr.SysConfigParams.LabelPrinterName}, 模板路径={model.LabelTempPath}, 打印数据={CurrPrintInfos}", WarningEnum.Low);
  6300. }
  6301. if (model.EnableExcelPrint)
  6302. {
  6303. Log("Excel打印", $"打印机:{confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.ExcelTempPath}");
  6304. ret = PrintFileData(PrinterType.Excel, confMgr.SysConfigParams.ExcelPrinterName,
  6305. model.ExcelTempPath, CurrPrintInfos, model);
  6306. if (ret)
  6307. Log("Excel打印", $"打印成功:{CurrPrintInfos}");
  6308. else
  6309. Log("Excel打印", $"打印失败:打印机={confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.ExcelTempPath}, 打印数据={CurrPrintInfos}", WarningEnum.Low);
  6310. }
  6311. //获取当前工单
  6312. CurrDefectOrders = OrderService.GetListNav(order.DetectOrder);
  6313. if (model.EnableOrderPrint && (CurrDefectOrders.Count == TotalCnt))
  6314. {
  6315. DialogResult result = MessageBox.Show($"工单检测完成,数量{CurrDefectOrders.Count},是否打印?", "检验工单打印",
  6316. MessageBoxButtons.YesNo);
  6317. if (result == DialogResult.Yes)
  6318. {
  6319. Log("工单打印", $"打印机:{confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.OrderTempPath}");
  6320. ret = PrintFileOrderData(confMgr.SysConfigParams.ExcelPrinterName,
  6321. model.OrderTempPath, CurrOrderPrintInfos, model);
  6322. if (ret)
  6323. Log("工单打印", $"打印成功!");
  6324. else
  6325. Log("工单打印", $"打印失败:打印机={confMgr.SysConfigParams.ExcelPrinterName}, 模板路径={model.OrderTempPath}, 打印数据={CurrOrderPrintInfos}", WarningEnum.Low);
  6326. }
  6327. }
  6328. #endregion
  6329. return -1;
  6330. }
  6331. else //继续
  6332. {
  6333. if (this.CurrPoinntCount >= TestCnt )
  6334. {
  6335. CurrStepResult = 0;
  6336. this.CurrPoinntCount = 0;
  6337. lstTestData.Clear();
  6338. //新流程需要判断是否跑完该流程所有点位
  6339. return ++stepIndex;
  6340. }
  6341. else
  6342. return stepIndex;
  6343. }
  6344. #endregion
  6345. }
  6346. }
  6347. catch (Exception ex)
  6348. {
  6349. Log("工序", $"[{stepIndex + 1}] Err:" + ex.Message + "\n" + ex.StackTrace, WarningEnum.High);
  6350. return -2;
  6351. }
  6352. }
  6353. #region 缺陷数量
  6354. /// <summary>
  6355. /// 根据缺陷code获取缺陷数量
  6356. /// </summary>
  6357. /// <param name="order"></param>
  6358. /// <param name="defectCodeEnum"></param>
  6359. /// <returns></returns>
  6360. private int getDefectCountFromCode(Order order, DefectCodeEnum defectCodeEnum)
  6361. {
  6362. switch (defectCodeEnum)
  6363. {
  6364. case DefectCodeEnum.dk:
  6365. return order.DKCount;
  6366. case DefectCodeEnum.zw:
  6367. return order.ZWCount;
  6368. case DefectCodeEnum.gsyc:
  6369. return order.GSYCCount;
  6370. case DefectCodeEnum.xws:
  6371. return order.XWSCount;
  6372. case DefectCodeEnum.qk:
  6373. return order.QKCount;
  6374. case DefectCodeEnum.zk:
  6375. return order.ZKCount;
  6376. case DefectCodeEnum.pp:
  6377. return order.PPCount;
  6378. case DefectCodeEnum.hs:
  6379. return order.HSCount;
  6380. case DefectCodeEnum.yx:
  6381. return order.YXCount;
  6382. case DefectCodeEnum.xb:
  6383. return order.XBCount;
  6384. case DefectCodeEnum.sx:
  6385. return order.SXCount;
  6386. case DefectCodeEnum.ds:
  6387. return order.DSCount;
  6388. //case DefectCodeEnum.gsdl:
  6389. // return order.GSDLCount;
  6390. //case DefectCodeEnum.cjdk:
  6391. // return order.CJDKCount;
  6392. default:
  6393. return 0;
  6394. }
  6395. }
  6396. #endregion
  6397. #region 厚度检测
  6398. /// <summary>
  6399. /// 厚度检测
  6400. /// </summary>
  6401. /// <param name="stepIndex"></param>
  6402. /// <param name="param"></param>
  6403. /// <param name="isBase"></param>
  6404. /// <returns></returns>
  6405. private int HeightProcessTest(int stepIndex, string processName, string param, bool isBase)
  6406. {
  6407. int ret = 0;
  6408. if (!WaitAllAxisDone())//因启用轴异步功能,使用前需等待
  6409. {
  6410. Log($"厚度基准测量", $"轴到位失败!", WarningEnum.High);
  6411. return stepIndex;
  6412. }
  6413. //判断是否有产品
  6414. bool sts;
  6415. if(isBase) //打基准
  6416. {
  6417. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.产品有无), GetIOBitIndex((int)DIName.产品有无), out sts);
  6418. if(sts)
  6419. {
  6420. Log($"厚度基准测量", $"存在产品,请下料,并重新开始!", WarningEnum.High);
  6421. return -1;
  6422. }
  6423. //开启线程自动打基准
  6424. Thread t = new System.Threading.Thread(()=>RunGetHeightValue(stepIndex, processName, param, isBase));
  6425. t.IsBackground = true;
  6426. t.Start();
  6427. }
  6428. return ret;
  6429. }
  6430. private void RunGetHeightValue(int stepIndex, string processName, string param, bool isBase)
  6431. {
  6432. int AxisX = (int)AxisName.Axis0;
  6433. int AxisY = (int)AxisName.Axis2;
  6434. List<int> axislist = new List<int>() { AxisX, AxisY };
  6435. JObject processParam = JObject.Parse(param);
  6436. int TestCnt = processParam.Value<int>("TestCnt");
  6437. DataProcess dataProcess = (DataProcess)processParam.Value<int>("ProcessData");
  6438. int DelayTime = processParam.Value<int>("DelayTime");
  6439. int DataCnt = processParam.Value<int>("DataCnt");
  6440. double OffsetValue = processParam.Value<double>("OffsetValue");
  6441. //List<PointF> Points = processParam.Value<List<PointF>>("Points");
  6442. ThicknessProp thicknessParam = JsonConvert.DeserializeObject<ThicknessProp>(param);
  6443. List<PointF> Points = thicknessParam.Points;
  6444. double VelLow = processParam.Value<double>("VelLow");
  6445. double VelHigh = processParam.Value<double>("VelHigh");
  6446. double Acc = processParam.Value<double>("Acc");
  6447. double Dec = processParam.Value<double>("Dec");
  6448. int WaitTime = processParam.Value<int>("WaitTime");
  6449. //开始循环测试
  6450. //打基准
  6451. if(isBase)
  6452. {
  6453. Log($"厚度基准值-{processName}", processParam.ToString());
  6454. if(TestCnt > Points.Count)
  6455. {
  6456. Log($"厚度基准值-{processName}", $"点位少于测试次数!", WarningEnum.High);
  6457. return;
  6458. }
  6459. for (int i = 0; i < Points.Count; i++)
  6460. {
  6461. Log($"厚度基准值-{processName}", $"点位{i+1}测试");
  6462. Log($"厚度基准值-{processName}",
  6463. $"XY准备(绝对)运动至{Points[i].X},{Points[i].Y}...");
  6464. if (axisDev.CheckDone(AxisX, 20) != 0)
  6465. {
  6466. Log($"厚度基准值-{processName}", $"轴X1到位失败!", WarningEnum.High);
  6467. return;
  6468. }
  6469. if (axisDev.CheckDone(AxisY, 20) != 0)
  6470. {
  6471. Log($"厚度基准值-{processName}", $"轴Y到位失败!", WarningEnum.High);
  6472. return;
  6473. }
  6474. VelocityCurveParams velx = new VelocityCurveParams(Acc, Dec, VelLow, VelHigh, MotionST, GetMMtoPlus((AxisName)AxisX));
  6475. VelocityCurveParams vely = new VelocityCurveParams(Acc, Dec, VelLow, VelHigh, MotionST, GetMMtoPlus((AxisName)AxisY));
  6476. int iret1 = 0;
  6477. int iret2 = 0;
  6478. iret1 = axisDev.MoveAbsValue(AxisX, velx, Points[i].X);
  6479. iret2 = axisDev.MoveAbsValue(AxisY, vely, Points[i].Y);
  6480. if (iret1 != 0)
  6481. {
  6482. Log($"厚度基准值-{processName}", $"轴X1运动失败!", WarningEnum.High);
  6483. return;
  6484. }
  6485. if (iret2 != 0)
  6486. {
  6487. Log($"厚度基准值-{processName}", $"轴Y运动失败!", WarningEnum.High);
  6488. return;
  6489. }
  6490. //多轴同时运行后强制等待各轴完成
  6491. Log($"厚度基准值-{processName}", $"等待轴组运行完成...");
  6492. if (!WaitAxisDone(axislist))
  6493. {
  6494. Log($"厚度基准值-{processName}", $"轴到位失败!", WarningEnum.High);
  6495. return;
  6496. }
  6497. Thread.Sleep(WaitTime);
  6498. Log($"厚度基准值-{processName}", $"轴组运行完成");
  6499. //测厚气缸下降
  6500. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), true);
  6501. Thread.Sleep(confMgr.HeightDoWait);
  6502. //读取数据
  6503. double TempVal = 0;
  6504. List<double> tempDataList = new List<double>();
  6505. for (int j = 0; j < DataCnt; j++)
  6506. {
  6507. Thread.Sleep(DelayTime);
  6508. TempVal = thicknessDev.GetValue();
  6509. if (TempVal < 0)
  6510. {
  6511. Log("厚度读取", "厚度读取失败,忽略此次测试!");
  6512. return;
  6513. }
  6514. tempDataList.Add(TempVal);
  6515. }
  6516. switch (dataProcess)
  6517. {
  6518. case DataProcess.均值:
  6519. TempVal = tempDataList.Average();
  6520. break;
  6521. case DataProcess.最大值:
  6522. TempVal = tempDataList.Max();
  6523. break;
  6524. case DataProcess.最小值:
  6525. TempVal = tempDataList.Min();
  6526. break;
  6527. default:
  6528. TempVal = tempDataList.Average();
  6529. Log("厚度读取", "厚度读取处理错误,启用均值!");
  6530. break;
  6531. }
  6532. TempVal = Math.Round(TempVal, 2);
  6533. Log("厚度读取", $"厚度值基准值{i+1}:{TempVal}");
  6534. lstHeightBase.Add(TempVal);
  6535. //测厚气缸上升
  6536. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.测厚气缸), GetIOBitIndex((int)DOName.测厚气缸), false);
  6537. Thread.Sleep(confMgr.HeightDoWait);
  6538. }
  6539. }
  6540. GotoLoadPos();
  6541. //打开加紧气缸
  6542. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.加紧气缸), GetIOBitIndex((int)DOName.加紧气缸), false);
  6543. IsCurrHeightBase = true;
  6544. Log("厚度读取", $"获取基准值完毕!");
  6545. }
  6546. #endregion
  6547. #region 双控
  6548. /// <summary>
  6549. /// 等待双控按钮按下
  6550. /// </summary>
  6551. /// <returns></returns>
  6552. private bool WaitGetStartSig()
  6553. {
  6554. bool ret = false;
  6555. bool sts;
  6556. if (!IsGetStartSig)
  6557. {
  6558. GotoLoadPos();
  6559. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), true);
  6560. Log($"双控启动", $"等待双控按下....");
  6561. while (true)
  6562. {
  6563. if (isBreakProcessRun())
  6564. {
  6565. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  6566. return false;
  6567. }
  6568. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.双手启动), GetIOBitIndex((int)DIName.双手启动), out sts);
  6569. if (sts)
  6570. {
  6571. if (confMgr.SysConfigParams.OpenPdtIsHave)
  6572. ioCardDev.GetDIBitState(GetIOPortIndex((int)DIName.产品有无), GetIOBitIndex((int)DIName.产品有无), out sts);
  6573. else
  6574. sts = true;
  6575. if (sts)
  6576. {
  6577. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.加紧气缸), GetIOBitIndex((int)DOName.加紧气缸), true);
  6578. Thread.Sleep(confMgr.ProductDoWait);
  6579. Log($"双控启动", $"双控按钮按下启动");
  6580. IsGetStartSig = true;
  6581. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  6582. return true;
  6583. }
  6584. else
  6585. {
  6586. Log($"双控启动", $"无产品信号");
  6587. ioCardDev.WriteBitState(GetIOPortIndex((int)DOName.双手启动绿灯), GetIOBitIndex((int)DOName.双手启动绿灯), false);
  6588. IsGetStartSig = false;
  6589. return false;
  6590. }
  6591. }
  6592. Thread.Sleep(100);
  6593. }
  6594. }
  6595. else
  6596. return true;
  6597. //return ret;
  6598. }
  6599. #endregion
  6600. #region Mark
  6601. /// <summary>
  6602. /// 自动获取mark位置
  6603. /// </summary>
  6604. /// <param name="StepIndex"></param>
  6605. /// <param name="ProcessName"></param>
  6606. /// <param name="EngineName"></param>
  6607. /// <param name="img"></param>
  6608. /// <param name="gbxBmpPath"></param>
  6609. /// <param name="getPosArray"></param>
  6610. /// <param name="asynRun"></param>
  6611. 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)
  6612. {
  6613. //HOperatorSet.WriteImage(img, "bmp", 0, "123.bmp");
  6614. if(adapter == null || adapter.Length == 0)
  6615. {
  6616. adapter = new int[9] { 5, 18 ,0,0,0,0,0,0,0};
  6617. }
  6618. else if(adapter.Max() == 0)
  6619. adapter = new int[9] { 5, 18, 0, 0, 0, 0, 0, 0, 0 };
  6620. if (getPosArray == null || getPosArray.Length == 0)
  6621. {
  6622. getPosArray = new double[23];
  6623. }
  6624. int typeIndex = 0;
  6625. scannerCBmpLoc bmpCBmpQueue = new scannerCBmpLoc("",1,2);
  6626. //判断是否是第一次寻找mark
  6627. if (IsMarkPic)
  6628. typeIndex = 3333;
  6629. else
  6630. {
  6631. bmpCBmpQueue = scannerCBmpQueue.Dequeue();
  6632. if (pointIndex == 0)
  6633. typeIndex = marktype == MarkCam.尺寸检测Mark ? 1111 : 111;
  6634. else if (pointIndex == 1)
  6635. typeIndex = marktype == MarkCam.尺寸检测Mark ? 2222 : 222;
  6636. else if (pointIndex == 2)
  6637. typeIndex = marktype == MarkCam.尺寸检测Mark ? 4444 : 444;
  6638. else if (pointIndex == 3)
  6639. typeIndex = marktype == MarkCam.尺寸检测Mark ? 3333 : 333;
  6640. }
  6641. //tag
  6642. string MarkTag = "";
  6643. if (IsMarkPic)
  6644. {
  6645. if (marktype == MarkCam.尺寸检测Mark)
  6646. MarkTag = "F_Mark_" + StepIndex;
  6647. else
  6648. {
  6649. if (pointIndex == 3)
  6650. MarkTag = "B_Pos";
  6651. else
  6652. MarkTag = "B_Mark_" + StepIndex;
  6653. }
  6654. }
  6655. else
  6656. {
  6657. if (marktype == MarkCam.尺寸检测Mark)
  6658. MarkTag = "F_Pos";
  6659. else
  6660. MarkTag = "B_Pos";
  6661. }
  6662. //需要偏移校正,index=0时不能异步 //10,20,30... 
  6663. AutoResetEvent endEvent = new AutoResetEvent(false);
  6664. SizeLib.add(new SizeTask()
  6665. {
  6666. stepIndex = StepIndex,
  6667. processName = ProcessName,
  6668. engineName = EngineName,
  6669. drawingPagePath = gbxBmpPath,
  6670. Himage = IsMarkPic? img.Clone() : bmpCBmpQueue.Himage.Clone(),//bmp/file_path二选一,优先bmp
  6671. file_path = bmpCBmpQueue.Path,
  6672. posX = bmpCBmpQueue.PosX,
  6673. posY = bmpCBmpQueue.PosY,
  6674. sizeTag = MarkTag,
  6675. //2023-10-27
  6676. Adapter = adapter,
  6677. AdapterPos = getPosArray,
  6678. index = typeIndex,//Mark
  6679. ContoursAffineTrans1_Out = this.contoursAffineTrans1_Out,//只有777时才使用最近333输出的结果
  6680. finishEvent = (res) =>
  6681. {
  6682. try
  6683. {
  6684. if (res.index == 111 || res.index == 222 || res.index == 333 || res.index == 444)
  6685. {
  6686. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找缺陷Mark点 Index={res.index},结果记录...");
  6687. if (res.index == 333) this.contoursAffineTrans1_Out = res.ContoursAffineTrans1_Out;//不管成功失败都替换
  6688. if (res.isSucceed)
  6689. {
  6690. Thread.Sleep(100);
  6691. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找缺陷Mark点 Index={res.index}; 当前值:{string.Join(",", res.MarkPointList)}");
  6692. JArray markDatas;
  6693. if (string.IsNullOrWhiteSpace(order.MarkData))
  6694. markDatas = new JArray() { 0, 0, 0, 0, 0, 0, 0, 0 };
  6695. else
  6696. markDatas = JArray.Parse(order.MarkData);
  6697. for (int i = 0; i < res.MarkPointList.Count(); i++)
  6698. if (res.MarkPointList[i] != 0)
  6699. markDatas[i] = res.MarkPointList[i];
  6700. order.MarkData = markDatas.ToString();
  6701. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index},Mark点:{order.MarkData} "));
  6702. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找缺陷Mark点 Index={res.index};合并后:{order.MarkData}");
  6703. }
  6704. else
  6705. {
  6706. OnAutoRuning(new RunEventArgs(res.stepIndex, "Mark寻找", new List<double>(), 0, 0, 0, 3, false));
  6707. Log($"{res.stepIndex + 1}-{res.processName}", $"Mark点计算失败,index:{res.index}.", confMgr.SysConfigParams.OpenMarkErrorStop ? WarningEnum.High : WarningEnum.Normal);
  6708. }
  6709. //保存
  6710. if (confMgr.SysConfigParams.SizeBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeBigImag.SavePath))
  6711. {
  6712. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  6713. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{picName}.bmp";
  6714. if (res.Himage != null)
  6715. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  6716. else
  6717. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  6718. }
  6719. }
  6720. else
  6721. {
  6722. int roundIndex = res.index % 10;
  6723. if (res.isSucceed)
  6724. {
  6725. string tagOutData = "";
  6726. if (res.index == 3333 && !string.IsNullOrWhiteSpace(res.sizeTag))
  6727. {
  6728. tagOutData = $"自动寻找尺寸Mark点位:[{string.Join(",", res.posePT)}]";
  6729. if (res.posePT.Length < 2 || res.posePT.Length % 2 != 0)
  6730. {
  6731. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark出错: {tagOutData}", WarningEnum.High);
  6732. return;
  6733. }
  6734. //2023-10-27
  6735. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark对应Adapter: {string.Join(",", res.Adapter)}", WarningEnum.Normal);
  6736. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark对应AdapterPos: {string.Join(",", res.AdapterPos)}", WarningEnum.Normal);
  6737. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark对应posePT: {tagOutData}", WarningEnum.Normal);
  6738. if (order.SizeTagDataList == null)
  6739. order.SizeTagDataList = new List<SizeTagData>();
  6740. order.SizeTagDataList.Add(new SizeTagData()
  6741. {
  6742. SizeTag = res.sizeTag,
  6743. CreateStepIndex = res.stepIndex + 1,
  6744. posePT = string.Join(",", res.posePT)// 回转 Array.ConvertAll(sNums , double.Parse);
  6745. });
  6746. }
  6747. //OnAutoRuning(new RunEventArgs(liStatocStepIndex,
  6748. // $"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}"));
  6749. //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} ");
  6750. }
  6751. //失败
  6752. else
  6753. {
  6754. OnAutoRuning(new RunEventArgs(res.stepIndex, "Mark寻找", new List<double>(), 0, 0, 0, 3, false));
  6755. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark对应Adapter: {string.Join(",", res.Adapter)}", WarningEnum.Normal);
  6756. Log($"{res.stepIndex + 1}-{res.processName}", $"自动寻找尺寸Mark对应AdapterPos: {string.Join(",", res.AdapterPos)}", WarningEnum.Normal);
  6757. Log($"{res.stepIndex + 1}-{res.processName}", $"Mark点计算失败,index:{res.index}.", confMgr.SysConfigParams.OpenMarkErrorStop ? WarningEnum.High : WarningEnum.Normal);
  6758. }
  6759. //保存
  6760. if (confMgr.SysConfigParams.SizeBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeBigImag.SavePath))
  6761. {
  6762. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  6763. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{picName}.bmp";
  6764. if (res.Himage != null)
  6765. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  6766. else
  6767. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  6768. }
  6769. }
  6770. }
  6771. catch (Exception ex)
  6772. {
  6773. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测回调处理异常 index:{res.index},ex={ex.Message}");
  6774. }
  6775. endEvent.Set();//roundIndex=0成功或失败线程返回
  6776. //---
  6777. if (res.Himage != null)
  6778. {
  6779. res.Himage.Dispose();
  6780. res.Himage = null;
  6781. }
  6782. }
  6783. });
  6784. //需等上面异步回调中的相对偏移校正完成再继续
  6785. if (!asynRun)
  6786. {
  6787. if (!endEvent.WaitOne(10000))
  6788. {
  6789. Log($"{StepIndex + 1}-{ProcessName}", $"Mark位置获取等待超时,忽略继续!", WarningEnum.Low);
  6790. return false;
  6791. }
  6792. }
  6793. return true;
  6794. }
  6795. #endregion
  6796. #region PT线宽等处理
  6797. /// <summary>
  6798. /// 获取上下限
  6799. /// </summary>
  6800. /// <param name="index"></param>
  6801. /// <param name="data"></param>
  6802. /// <param name="aveData"></param>
  6803. /// <param name="model"></param>
  6804. /// <param name="testParam"></param>
  6805. /// <param name="Max"></param>
  6806. /// <param name="Min"></param>
  6807. /// <param name="TestName"></param>
  6808. private void GetLimitInfo(int index, double data, double aveData, Product model, PointTestProp testParam,
  6809. out double Max, out double Min, out string TestName )
  6810. {
  6811. double PtUpper = 0;
  6812. double PtLower = 0;
  6813. string testName = "";
  6814. //上下限设置
  6815. switch (index)
  6816. {
  6817. #region 单点
  6818. case 8001:
  6819. Log($"线宽值", $"线宽{lstTestData.Count}:{data}");
  6820. if (testParam.OpenUseLimit)
  6821. {
  6822. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6823. PtLower = testParam.StandardValues - testParam.MinLimit;
  6824. }
  6825. else
  6826. {
  6827. PtUpper = model.LineWidthBaseValue + model.LineWidthUpFloatValue;
  6828. PtLower = model.LineWidthBaseValue - model.LineWidthDownFloatValue;
  6829. }
  6830. if (order != null)
  6831. order.LineWidthValue = aveData;
  6832. testName = "线宽正面";
  6833. break;
  6834. case 8002:
  6835. Log($"反面检测值", $"反面检测{lstTestData.Count}:{data}");
  6836. if (testParam.OpenUseLimit)
  6837. {
  6838. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6839. PtLower = testParam.StandardValues - testParam.MinLimit;
  6840. }
  6841. else
  6842. {
  6843. PtUpper = model.FLineWidthBaseValue + model.FLineWidthUpFloatValue;
  6844. PtLower = model.FLineWidthBaseValue - model.FLineWidthDownFloatValue;
  6845. }
  6846. if (order != null)
  6847. order.FLineWidthValue = aveData;
  6848. testName = "反面检测";
  6849. break;
  6850. case 8007:
  6851. Log($"背极宽度值", $"背极宽度{lstTestData.Count}:{data}");
  6852. if (testParam.OpenUseLimit)
  6853. {
  6854. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6855. PtLower = testParam.StandardValues - testParam.MinLimit;
  6856. }
  6857. else
  6858. {
  6859. PtUpper = model.BackPoleWidthBaseValue + model.BackPoleWidthUpFloatValue;
  6860. PtLower = model.BackPoleWidthBaseValue - model.BackPoleWidthDownFloatValue;
  6861. }
  6862. if (order != null)
  6863. order.BackPoleWidthValue = aveData;
  6864. testName = "背极宽度";
  6865. break;
  6866. case 8003:
  6867. Log($"鱼叉口宽值", $"鱼叉口宽{lstTestData.Count}:{data}");
  6868. if (testParam.OpenUseLimit)
  6869. {
  6870. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6871. PtLower = testParam.StandardValues - testParam.MinLimit;
  6872. }
  6873. else
  6874. {
  6875. PtUpper = model.ForkWidthBaseValue + model.ForkWidthUpFloatValue;
  6876. PtLower = model.ForkWidthBaseValue - model.ForkWidthDownFloatValue;
  6877. }
  6878. if (order != null)
  6879. order.ForkWidthValue = aveData;
  6880. testName = "鱼叉口宽";
  6881. break;
  6882. case 8004:
  6883. Log($"蜈蚣角宽值", $"蜈蚣角宽{lstTestData.Count}:{data}");
  6884. if (testParam.OpenUseLimit)
  6885. {
  6886. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6887. PtLower = testParam.StandardValues - testParam.MinLimit;
  6888. }
  6889. else
  6890. {
  6891. PtUpper = model.ChilopodWidthBaseValue + model.ChilopodWidthUpFloatValue;
  6892. PtLower = model.ChilopodWidthBaseValue - model.ChilopodWidthDownFloatValue;
  6893. }
  6894. if (order != null)
  6895. order.ChilopodWidthValue = aveData;
  6896. testName = "蜈蚣角宽";
  6897. break;
  6898. case 8005:
  6899. Log($"主栅宽度检测值", $"主栅宽度检测{lstTestData.Count}:{data}");
  6900. if (testParam.OpenUseLimit)
  6901. {
  6902. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6903. PtLower = testParam.StandardValues - testParam.MinLimit;
  6904. }
  6905. else
  6906. {
  6907. PtUpper = model.MGridWidthBaseValue + model.MGridWidthUpFloatValue;
  6908. PtLower = model.MGridWidthBaseValue - model.MGridWidthDownFloatValue;
  6909. }
  6910. if (order != null)
  6911. order.MGridWidthValue = aveData;
  6912. testName = "主栅宽度检测";
  6913. break;
  6914. #endregion
  6915. #region 双点
  6916. case 8102:
  6917. Log($"Y-PT值", $"PT{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  6918. if (order != null)
  6919. order.PTValue = aveData;
  6920. if (testParam.OpenUseLimit)
  6921. {
  6922. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6923. PtLower = testParam.StandardValues - testParam.MinLimit;
  6924. }
  6925. else
  6926. {
  6927. PtUpper = model.PTBaseValue + model.PTUpFloatValue;
  6928. PtLower = model.PTBaseValue - model.PTDownFloatValue;
  6929. }
  6930. testName = "Y轴方向PT值检测";
  6931. break;
  6932. case 8202:
  6933. Log($"X-PT值", $"PT{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  6934. if (order != null)
  6935. order.XPTValue = aveData;
  6936. if (testParam.OpenUseLimit)
  6937. {
  6938. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6939. PtLower = testParam.StandardValues - testParam.MinLimit;
  6940. }
  6941. else
  6942. {
  6943. PtUpper = model.PTXBaseValue + model.PTXUpFloatValue;
  6944. PtLower = model.PTXBaseValue - model.PTXDownFloatValue;
  6945. }
  6946. testName = "X轴方向PT值检测";
  6947. break;
  6948. case 8302:
  6949. Log($"主栅连接线检测值", $"主栅连接线检测{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  6950. if (order != null)
  6951. order.MGridIntervalValue = aveData;
  6952. if (testParam.OpenUseLimit)
  6953. {
  6954. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6955. PtLower = testParam.StandardValues - testParam.MinLimit;
  6956. }
  6957. else
  6958. {
  6959. PtUpper = model.MGridIntervalBaseValue + model.MGridIntervalUpFloatValue;
  6960. PtLower = model.MGridIntervalBaseValue - model.MGridIntervalDownFloatValue;
  6961. }
  6962. testName = "主栅连接线检测";
  6963. break;
  6964. case 8402:
  6965. Log($"主栅宽度检测值", $"主栅宽度检测{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  6966. if (order != null)
  6967. order.MGridWidthValue = aveData;
  6968. if (testParam.OpenUseLimit)
  6969. {
  6970. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6971. PtLower = testParam.StandardValues - testParam.MinLimit;
  6972. }
  6973. else
  6974. {
  6975. PtUpper = model.MGridWidthBaseValue + model.MGridWidthUpFloatValue;
  6976. PtLower = model.MGridWidthBaseValue - model.MGridWidthDownFloatValue;
  6977. }
  6978. testName = "主栅宽度检测";
  6979. break;
  6980. case 8502:
  6981. Log($"主栅间距值", $"主栅间距{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  6982. if (order != null)
  6983. order.MGridSpreadValue = aveData;
  6984. if (testParam.OpenUseLimit)
  6985. {
  6986. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  6987. PtLower = testParam.StandardValues - testParam.MinLimit;
  6988. }
  6989. else
  6990. {
  6991. PtUpper = model.MGridSpreadBaseValue + model.MGridSpreadUpFloatValue;
  6992. PtLower = model.MGridSpreadBaseValue - model.MGridSpreadDownFloatValue;
  6993. }
  6994. testName = "主栅间距";
  6995. break;
  6996. case 8602:
  6997. Log($"细栅间距检测值", $"细栅间距检测{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  6998. if (order != null)
  6999. order.FGridSpreadValue = aveData;
  7000. if (testParam.OpenUseLimit)
  7001. {
  7002. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7003. PtLower = testParam.StandardValues - testParam.MinLimit;
  7004. }
  7005. else
  7006. {
  7007. PtUpper = model.FGridSpreadBaseValue + model.FGridSpreadUpFloatValue;
  7008. PtLower = model.FGridSpreadBaseValue - model.FGridSpreadDownFloatValue;
  7009. }
  7010. testName = "细栅间距检测";
  7011. break;
  7012. case 8702:
  7013. Log($"主栅长度检测值", $"主栅长度检测{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7014. if (order != null)
  7015. order.MGridLengthValue = aveData;
  7016. if (testParam.OpenUseLimit)
  7017. {
  7018. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7019. PtLower = testParam.StandardValues - testParam.MinLimit;
  7020. }
  7021. else
  7022. {
  7023. PtUpper = model.MGridLengthBaseValue + model.MGridLengthUpFloatValue;
  7024. PtLower = model.MGridLengthBaseValue - model.MGridLengthDownFloatValue;
  7025. }
  7026. testName = "主栅长度检测";
  7027. break;
  7028. case 8802:
  7029. Log($"Mark点横向间距值", $"Mark点横向间距{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7030. if (order != null)
  7031. order.MarkXDisValue = aveData;
  7032. if (testParam.OpenUseLimit)
  7033. {
  7034. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7035. PtLower = testParam.StandardValues - testParam.MinLimit;
  7036. }
  7037. else
  7038. {
  7039. PtUpper = model.MarkXDisBaseValue + model.MarkXDisUpFloatValue;
  7040. PtLower = model.MarkXDisBaseValue - model.MarkXDisDownFloatValue;
  7041. }
  7042. testName = "Mark点横向间距";
  7043. break;
  7044. case 8902:
  7045. Log($"Mark点竖向间距值", $"Mark点竖向间距{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7046. if (order != null)
  7047. order.MarkYDisValue = aveData;
  7048. if (testParam.OpenUseLimit)
  7049. {
  7050. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7051. PtLower = testParam.StandardValues - testParam.MinLimit;
  7052. }
  7053. else
  7054. {
  7055. PtUpper = model.MarkYDisBaseValue + model.MarkYDisUpFloatValue;
  7056. PtLower = model.MarkYDisBaseValue - model.MarkYDisDownFloatValue;
  7057. }
  7058. testName = "Mark点竖向间距";
  7059. break;
  7060. case 9102:
  7061. Log($"鱼叉口长值", $"鱼叉口长{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7062. if (order != null)
  7063. order.ForkLengthValue = aveData;
  7064. if (testParam.OpenUseLimit)
  7065. {
  7066. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7067. PtLower = testParam.StandardValues - testParam.MinLimit;
  7068. }
  7069. else
  7070. {
  7071. PtUpper = model.ForkLengthBaseValue + model.ForkLengthUpFloatValue;
  7072. PtLower = model.ForkLengthBaseValue - model.ForkLengthDownFloatValue;
  7073. }
  7074. testName = "鱼叉口长";
  7075. break;
  7076. case 9302:
  7077. Log($"鱼叉口间距值", $"鱼叉口间距{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7078. if (order != null)
  7079. order.ForkDisValue = aveData;
  7080. if (testParam.OpenUseLimit)
  7081. {
  7082. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7083. PtLower = testParam.StandardValues - testParam.MinLimit;
  7084. }
  7085. else
  7086. {
  7087. PtUpper = model.ForkDisBaseValue + model.ForkDisUpFloatValue;
  7088. PtLower = model.ForkDisBaseValue - model.ForkDisDownFloatValue;
  7089. }
  7090. testName = "鱼叉口间距检测";
  7091. break;
  7092. case 9402:
  7093. Log($"蜈蚣角长值", $"蜈蚣角长{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7094. if (order != null)
  7095. order.ChilopodLengthValue = aveData;
  7096. if (testParam.OpenUseLimit)
  7097. {
  7098. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7099. PtLower = testParam.StandardValues - testParam.MinLimit;
  7100. }
  7101. else
  7102. {
  7103. PtUpper = model.ChilopodLengthBaseValue + model.ChilopodLengthUpFloatValue;
  7104. PtLower = model.ChilopodLengthBaseValue - model.ChilopodLengthDownFloatValue;
  7105. }
  7106. testName = "蜈蚣角长检测";
  7107. break;
  7108. case 9502:
  7109. Log($"分片间隔长值", $"分片间隔{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7110. if (order != null)
  7111. order.ShardingDisValue = aveData;
  7112. if (testParam.OpenUseLimit)
  7113. {
  7114. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7115. PtLower = testParam.StandardValues - testParam.MinLimit;
  7116. }
  7117. else
  7118. {
  7119. PtUpper = model.ShardingDisBaseValue + model.ShardingDisUpFloatValue;
  7120. PtLower = model.ShardingDisBaseValue - model.ShardingDisDownFloatValue;
  7121. }
  7122. testName = "分片间隔检测";
  7123. break;
  7124. case 9602:
  7125. Log($"焊点长值", $"焊点长{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7126. if (order != null)
  7127. order.WeldingSpotLengthValue = aveData;
  7128. if (testParam.OpenUseLimit)
  7129. {
  7130. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7131. PtLower = testParam.StandardValues - testParam.MinLimit;
  7132. }
  7133. else
  7134. {
  7135. PtUpper = model.WeldingSpotLengthBaseValue + model.WeldingSpotLengthUpFloatValue;
  7136. PtLower = model.WeldingSpotLengthBaseValue - model.WeldingSpotLengthDownFloatValue;
  7137. }
  7138. testName = "焊点长检测";
  7139. break;
  7140. case 9702:
  7141. Log($"焊点宽值", $"焊点宽{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7142. if (order != null)
  7143. order.WeldingSpotWidthValue = aveData;
  7144. if (testParam.OpenUseLimit)
  7145. {
  7146. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7147. PtLower = testParam.StandardValues - testParam.MinLimit;
  7148. }
  7149. else
  7150. {
  7151. PtUpper = model.WeldingSpotWidthBaseValue + model.WeldingSpotWidthUpFloatValue;
  7152. PtLower = model.WeldingSpotWidthBaseValue - model.WeldingSpotWidthDownFloatValue;
  7153. }
  7154. testName = "焊点宽检测";
  7155. break;
  7156. case 9802:
  7157. Log($"焊点间隔值", $"焊点间隔{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7158. if (order != null)
  7159. order.WeldingSpotDisValue = aveData;
  7160. if (testParam.OpenUseLimit)
  7161. {
  7162. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7163. PtLower = testParam.StandardValues - testParam.MinLimit;
  7164. }
  7165. else
  7166. {
  7167. PtUpper = model.WeldingSpotDisBaseValue + model.WeldingSpotDisUpFloatValue;
  7168. PtLower = model.WeldingSpotDisBaseValue - model.WeldingSpotDisDownFloatValue;
  7169. }
  7170. testName = "焊点间隔检测";
  7171. break;
  7172. case 9902:
  7173. Log($"SP2主栅宽度值", $"SP2主栅宽度{lstTestData.Count}:{Math.Round(data + testParam.OffsetValue, 4)}");
  7174. //if (order != null)
  7175. // order.WeldingSpotDisValue = aveData;
  7176. if (testParam.OpenUseLimit)
  7177. {
  7178. PtUpper = testParam.StandardValues + testParam.MaxLimit;
  7179. PtLower = testParam.StandardValues - testParam.MinLimit;
  7180. }
  7181. else
  7182. {
  7183. PtUpper = 0;
  7184. PtLower = 0;
  7185. }
  7186. testName = "SP2主栅宽度检测";
  7187. break;
  7188. #endregion
  7189. }
  7190. Max = PtUpper;
  7191. Min = PtLower;
  7192. TestName = testName;
  7193. }
  7194. /// <summary>
  7195. /// 保存均值
  7196. /// </summary>
  7197. /// <param name="stepName"></param>
  7198. /// <param name="testName"></param>
  7199. /// <param name="AveData"></param>
  7200. /// <param name="max"></param>
  7201. /// <param name="min"></param>
  7202. /// <returns></returns>
  7203. private bool AddAverageData(string stepName,string testName, double AveData, double max, double min)
  7204. {
  7205. if (order.SizeDefectAverageInfoList == null)
  7206. order.SizeDefectAverageInfoList = new List<SizeDefectAverageInfo>();
  7207. //寻找对应测试项是否已经保存
  7208. var temp = order.SizeDefectAverageInfoList.Where(x => (x.StepName.Contains(stepName) && x.PointCode.Contains(testName))).FirstOrDefault();
  7209. if (temp == null)
  7210. {
  7211. //为保存数据存入
  7212. order.SizeDefectAverageInfoList.Add(new SizeDefectAverageInfo()
  7213. {
  7214. result = CurrStepResult == 2 ? 2 : 1,
  7215. Max = max,
  7216. Min = min,
  7217. PointCode = testName,
  7218. AverageData = AveData,
  7219. StepName = stepName,
  7220. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7221. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  7222. });
  7223. }
  7224. else
  7225. {
  7226. temp.AverageData = AveData;
  7227. temp.Max = max;
  7228. temp.Min = min;
  7229. }
  7230. return true;
  7231. }
  7232. private bool PointTestDef(int stepIndex, string processName, string EngineName, string gbxBmpPath, bool asynRun, Product model, PointTestProp testParam, bool isPtLastPoint)
  7233. {
  7234. if (scannerCBmpQueue.Count < 1)
  7235. {
  7236. Log($"{stepIndex + 1}-{processName}", $"选点测试检测异常,无源图像!!", WarningEnum.Low);
  7237. return false;
  7238. }
  7239. var bmpCBmpQueue = scannerCBmpQueue.Dequeue();
  7240. Log($"{stepIndex + 1}-{processName}", $"开始选点检测,posX:{bmpCBmpQueue.PosX},posY:{bmpCBmpQueue.PosY},图像队列数量: {scannerCBmpQueue.Count}...");
  7241. int testindex = 0;
  7242. //判断测试项
  7243. switch (testParam.TestType)
  7244. {
  7245. case PointTestType.Y轴方向PT值检测:
  7246. if(!isPtLastPoint)
  7247. testindex = 8101;
  7248. else
  7249. testindex = 8102;
  7250. break;
  7251. case PointTestType.线宽正面:
  7252. testindex = 8001;
  7253. break;
  7254. case PointTestType.反面检测:
  7255. testindex = 8002;
  7256. break;
  7257. case PointTestType.X轴方向PT值检测:
  7258. if (!isPtLastPoint)
  7259. testindex = 8201;
  7260. else
  7261. testindex = 8202;
  7262. break;
  7263. case PointTestType.主栅连接线检测:
  7264. if (!isPtLastPoint)
  7265. testindex = 8301;
  7266. else
  7267. testindex = 8302;
  7268. break;
  7269. case PointTestType.主栅宽度检测:
  7270. testindex = 8005;
  7271. break;
  7272. case PointTestType.主栅间距:
  7273. if (!isPtLastPoint)
  7274. testindex = 8501;
  7275. else
  7276. testindex = 8502;
  7277. break;
  7278. case PointTestType.细栅间距检测:
  7279. if (!isPtLastPoint)
  7280. testindex = 8601;
  7281. else
  7282. testindex = 8602;
  7283. break;
  7284. case PointTestType.背极宽度:
  7285. testindex = 8007;
  7286. break;
  7287. case PointTestType.主栅长度检测:
  7288. if (!isPtLastPoint)
  7289. testindex = 8701;
  7290. else
  7291. testindex = 8702;
  7292. break;
  7293. case PointTestType.Mark点横向间距:
  7294. if (!isPtLastPoint)
  7295. testindex = 8801;
  7296. else
  7297. testindex = 8802;
  7298. break;
  7299. case PointTestType.Mark点竖向间距:
  7300. if (!isPtLastPoint)
  7301. testindex = 8901;
  7302. else
  7303. testindex = 8902;
  7304. break;
  7305. case PointTestType.鱼叉口长:
  7306. if (!isPtLastPoint)
  7307. testindex = 9101;
  7308. else
  7309. testindex = 9102;
  7310. break;
  7311. case PointTestType.鱼叉口宽:
  7312. testindex = 8003;
  7313. break;
  7314. case PointTestType.鱼叉口间距:
  7315. if (!isPtLastPoint)
  7316. testindex = 9301;
  7317. else
  7318. testindex = 9302;
  7319. break;
  7320. case PointTestType.蜈蚣角长:
  7321. if (!isPtLastPoint)
  7322. testindex = 9401;
  7323. else
  7324. testindex = 9402;
  7325. break;
  7326. case PointTestType.蜈蚣角宽:
  7327. testindex = 8004;
  7328. break;
  7329. case PointTestType.分片间隔:
  7330. if (!isPtLastPoint)
  7331. testindex = 9501;
  7332. else
  7333. testindex = 9502;
  7334. break;
  7335. case PointTestType.焊点长:
  7336. if (!isPtLastPoint)
  7337. testindex = 9601;
  7338. else
  7339. testindex = 9602;
  7340. break;
  7341. case PointTestType.焊点宽:
  7342. if (!isPtLastPoint)
  7343. testindex = 9701;
  7344. else
  7345. testindex = 9702;
  7346. break;
  7347. case PointTestType.焊点间隔:
  7348. if (!isPtLastPoint)
  7349. testindex = 9801;
  7350. else
  7351. testindex = 9802;
  7352. break;
  7353. case PointTestType.SP2主栅宽度:
  7354. if (!isPtLastPoint)
  7355. testindex = 9901;
  7356. else
  7357. testindex = 9902;
  7358. break;
  7359. default:
  7360. Log($"{stepIndex + 1}-{processName}", $"参数不支持!", WarningEnum.High);
  7361. return false;
  7362. }
  7363. //需要偏移校正,index=0时不能异步 //10,20,30... 
  7364. AutoResetEvent endEvent = new AutoResetEvent(false);
  7365. //加入处理
  7366. SizeLib.add(new SizeTask()
  7367. {
  7368. stepIndex = stepIndex,
  7369. processName = processName,
  7370. //sizeTag = sizeTag,
  7371. engineName = EngineName,
  7372. Himage = bmpCBmpQueue.Himage.Clone(),//bmp/file_path二选一,优先bmp
  7373. file_path = bmpCBmpQueue.Path,
  7374. drawingPagePath = gbxBmpPath,
  7375. posX = bmpCBmpQueue.PosX,
  7376. posY = bmpCBmpQueue.PosY,
  7377. index = testindex,//PT
  7378. ContoursAffineTrans1_Out = this.contoursAffineTrans1_Out,//只有777时才使用最近333输出的结果
  7379. //结果回调
  7380. finishEvent = (res) =>
  7381. {
  7382. try
  7383. {
  7384. int roundIndex = res.index % 10;
  7385. if (res.isSucceed)
  7386. {
  7387. string tagOutData = "";
  7388. OnAutoRuning(new RunEventArgs(stepIndex,
  7389. $"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}"));
  7390. 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} ");
  7391. //测量
  7392. //------TEST
  7393. if ((res.index == 8102)|| (res.index == 8202) || (res.index == 8302) || (res.index == 8402)
  7394. || (res.index == 8502) || (res.index == 8602) || (res.index == 8702) || (res.index == 8802)
  7395. || (res.index == 8902) || (res.index == 9102) || (res.index == 9202) || (res.index == 9302)
  7396. || (res.index == 9402) || (res.index == 9502) || (res.index == 9602) || (res.index == 9702)
  7397. || (res.index == 9802) || (res.index == 9902))
  7398. {
  7399. //PT测量 等两点测量
  7400. lock (lstTestData)
  7401. {
  7402. lstTestData.Add(Math.Round(res.PT1 + testParam.OffsetValue, 4));
  7403. double PtValue = Math.Round(lstTestData.Average(), 4);
  7404. double PtUpper = 0;
  7405. double PtLower = 0;
  7406. string testName = "";
  7407. //上下限设置
  7408. GetLimitInfo(res.index, res.PT1, PtValue, model, testParam, out PtUpper, out PtLower, out testName);
  7409. //OnAutoRuning(new RunEventArgs(22, lstTestData, model.PTBaseValue + model.PTUpFloatValue, model.PTBaseValue - model.PTDownFloatValue));
  7410. //数据判定
  7411. double judgData = 0;
  7412. if (testParam.JudgmentData == DataJudgment.单点)
  7413. judgData = Math.Round(res.PT1 + testParam.OffsetValue, 4);
  7414. else
  7415. judgData = Math.Round(lstTestData.Average(), 4);
  7416. //存在上下限,判断是否为不合格
  7417. if (PtUpper + PtLower > 0 && (judgData > PtUpper || judgData < PtLower))
  7418. {
  7419. //order.Qualified = false;
  7420. CurrStepResult = 2;
  7421. }
  7422. else if ((testParam.JudgmentData == DataJudgment.均值)
  7423. && (PtUpper + PtLower > 0 && !(judgData > PtUpper || judgData < PtLower)))
  7424. {
  7425. //order.Qualified = true;
  7426. CurrStepResult = 0;
  7427. }
  7428. //添加均值数据
  7429. AddAverageData(processName, testName, PtValue, PtUpper, PtLower);
  7430. if (order.SizeDefectInfoList == null)
  7431. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  7432. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  7433. {
  7434. result = CurrStepResult == 2 ? 2 : 1,
  7435. X = res.posX,
  7436. Y = res.posY,
  7437. PointCode = testName,
  7438. Data = Math.Round(res.PT1 + testParam.OffsetValue, 4),
  7439. StepName = processName,
  7440. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7441. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7442. isAverage = false
  7443. });
  7444. if ((this.CurrPoinntCount + 1) < testParam.PointCnt)
  7445. OnAutoRuning(new RunEventArgs(stepIndex, processName, new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 4),
  7446. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), 1, false));
  7447. else
  7448. {
  7449. order.Qualified = CurrStepResult > 0 ? false : order.Qualified;
  7450. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  7451. {
  7452. result = CurrStepResult == 2 ? 2 : 1,
  7453. X = res.posX,
  7454. Y = res.posY,
  7455. PointCode = testName,
  7456. Data = Math.Round(lstTestData.Average(), 4),
  7457. StepName = processName,
  7458. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7459. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7460. isAverage = true
  7461. });
  7462. //打印
  7463. PrintDataList(processName, testParam, PtValue, PtUpper, PtLower);
  7464. OnAutoRuning(new RunEventArgs(stepIndex, processName, new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 4),
  7465. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), CurrStepResult > 0 ? 3 : 2, false));
  7466. }
  7467. }
  7468. }
  7469. //线宽,反面,背极宽度
  7470. else if ((res.index == 8001) || (res.index == 8002) || (res.index == 8007) || (res.index == 8003) || (res.index == 8004)
  7471. || (res.index == 8005))
  7472. {
  7473. //线宽测量 等单点测量
  7474. lock (lstTestData)
  7475. {
  7476. double lineWidthValue = res.Shanxian > 0 ? Math.Round(res.Shanxian + testParam.OffsetValue, 4) : 0;
  7477. lstTestData.Add(lineWidthValue);
  7478. double LwValue = Math.Round(lstTestData.Average(), 4);
  7479. double LwUpper = 0;
  7480. double LwLower = 0;
  7481. string testName = "";
  7482. //上下限设置
  7483. GetLimitInfo(res.index, lineWidthValue, LwValue, model, testParam, out LwUpper, out LwLower, out testName);
  7484. //OnAutoRuning(new RunEventArgs(23, lstTestData, model.LineWidthBaseValue + model.LineWidthUpFloatValue, model.LineWidthBaseValue - model.LineWidthDownFloatValue));
  7485. //数据判定
  7486. double judgData = 0;
  7487. if (testParam.JudgmentData == DataJudgment.单点)
  7488. judgData = lineWidthValue;
  7489. else
  7490. judgData = LwValue;
  7491. //存在上下限,判断是否为不合格
  7492. if (LwUpper + LwLower > 0 && (judgData > LwUpper || judgData < LwLower))
  7493. {
  7494. //order.Qualified = false;
  7495. CurrStepResult = 2;
  7496. }
  7497. else if ((testParam.JudgmentData == DataJudgment.均值)
  7498. &&(LwUpper + LwLower > 0 && !(judgData > LwUpper || judgData < LwLower)))
  7499. {
  7500. //order.Qualified = true;
  7501. CurrStepResult = 0;
  7502. }
  7503. //添加均值数据
  7504. AddAverageData(processName, testName, LwValue, LwUpper, LwLower);
  7505. if (order.SizeDefectInfoList == null)
  7506. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  7507. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  7508. {
  7509. result = CurrStepResult == 2 ? 2 : 1,
  7510. X = res.posX,
  7511. Y = res.posY,
  7512. PointCode = testName,
  7513. Data = lineWidthValue,
  7514. StepName = processName,
  7515. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7516. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7517. isAverage = false
  7518. });
  7519. if ((this.CurrPoinntCount + 1) < testParam.PointCnt)
  7520. OnAutoRuning(new RunEventArgs(stepIndex, processName, new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 2),
  7521. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), 1, false));
  7522. else
  7523. {
  7524. order.Qualified = CurrStepResult > 0 ? false : order.Qualified;
  7525. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  7526. {
  7527. result = CurrStepResult == 2 ? 2 : 1,
  7528. X = res.posX,
  7529. Y = res.posY,
  7530. PointCode = testName,
  7531. Data = Math.Round(lstTestData.Average(), 4),
  7532. StepName = processName,
  7533. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7534. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7535. isAverage = true
  7536. });
  7537. //打印
  7538. PrintDataList(processName, testParam, LwValue, LwUpper, LwLower);
  7539. OnAutoRuning(new RunEventArgs(stepIndex, processName, new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 2),
  7540. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), CurrStepResult > 0 ? 3 : 2, false));
  7541. }
  7542. }
  7543. }
  7544. //其他距离检测
  7545. else
  7546. {
  7547. ;
  7548. }
  7549. }
  7550. //失败
  7551. else
  7552. {
  7553. //------TEST
  7554. if ((res.index == 8102) || (res.index == 8202) || (res.index == 8302) || (res.index == 8402)
  7555. || (res.index == 8502) || (res.index == 8602) || (res.index == 8702) || (res.index == 8802)
  7556. || (res.index == 8902) || (res.index == 9102) || (res.index == 9202) || (res.index == 9302)
  7557. || (res.index == 9402) || (res.index == 9502) || (res.index == 9602) || (res.index == 9702)
  7558. || (res.index == 9802) || (res.index == 9902))
  7559. {
  7560. //PT测量
  7561. lock (lstTestData)
  7562. {
  7563. lstTestData.Add(0);
  7564. double PtValue = Math.Round(lstTestData.Average(), 4);
  7565. string testName = "";
  7566. double PtUpper = 0;
  7567. double PtLower = 0;
  7568. GetLimitInfo(res.index, 0, PtValue, model, testParam, out PtUpper, out PtLower, out testName);
  7569. //OnAutoRuning(new RunEventArgs(stepIndex, processName, lstPT, Math.Round(lstPT.Average(), 4),
  7570. // Math.Round(lstPT.Max(), 4), Math.Round(lstPT.Min(), 4), 3, false));
  7571. order.Qualified = false;
  7572. CurrStepResult = 2;
  7573. //添加均值数据
  7574. AddAverageData(processName, testName, PtValue, PtUpper, PtLower);
  7575. if (order.SizeDefectInfoList == null)
  7576. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  7577. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  7578. {
  7579. result = CurrStepResult == 2 ? 2 : 1,
  7580. X = res.posX,
  7581. Y = res.posY,
  7582. PointCode = testName,
  7583. Data = 0,
  7584. StepName = processName,
  7585. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7586. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7587. isAverage = false
  7588. });
  7589. if ((this.CurrPoinntCount + 1) < testParam.PointCnt)
  7590. OnAutoRuning(new RunEventArgs(stepIndex, processName + ":检测失败", new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 4),
  7591. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), 1, false));
  7592. else
  7593. {
  7594. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  7595. {
  7596. result = CurrStepResult == 2 ? 2 : 1,
  7597. X = res.posX,
  7598. Y = res.posY,
  7599. PointCode = testName,
  7600. Data = Math.Round(lstTestData.Average(), 4),
  7601. StepName = processName,
  7602. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7603. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7604. isAverage = true
  7605. });
  7606. PrintDataList(processName, testParam, PtValue, PtUpper, PtLower);
  7607. OnAutoRuning(new RunEventArgs(stepIndex, processName + ":检测失败", new List<double>(lstTestData.ToArray()), Math.Round(lstTestData.Average(), 4),
  7608. Math.Round(lstTestData.Max(), 4), Math.Round(lstTestData.Min(), 4), CurrStepResult > 0 ? 3 : 2, false));
  7609. }
  7610. }
  7611. }
  7612. //------
  7613. else if ((res.index == 8001) || (res.index == 8002) || (res.index == 8007) || (res.index == 8003) || (res.index == 8004)
  7614. || (res.index == 8005))
  7615. {
  7616. //线宽测量
  7617. lock (lstTestData)
  7618. {
  7619. lstTestData.Add(0);
  7620. double LwValue = Math.Round(lstTestData.Average(), 2);
  7621. string testName = "";
  7622. double LwUpper = 0;
  7623. double LwLower = 0;
  7624. GetLimitInfo(res.index, 0, LwValue, model, testParam, out LwUpper, out LwLower, out testName);
  7625. order.Qualified = false;
  7626. CurrStepResult = 2;
  7627. //添加均值数据
  7628. AddAverageData(processName, testName, LwValue, LwUpper, LwLower);
  7629. if (order.SizeDefectInfoList == null)
  7630. order.SizeDefectInfoList = new List<SizeDefectInfo>();
  7631. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  7632. {
  7633. result = CurrStepResult == 2 ? 2 : 1,
  7634. X = res.posX,
  7635. Y = res.posY,
  7636. PointCode = testName,
  7637. Data = 0,
  7638. StepName = processName,
  7639. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7640. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7641. isAverage = false
  7642. });
  7643. if ((this.CurrPoinntCount + 1) < testParam.PointCnt)
  7644. OnAutoRuning(new RunEventArgs(stepIndex, processName + ":检测失败", lstTestData, Math.Round(lstTestData.Average(), 2),
  7645. Math.Round(lstTestData.Max(), 2), Math.Round(lstTestData.Min(), 2), 1, false));
  7646. else
  7647. {
  7648. order.SizeDefectInfoList.Add(new SizeDefectInfo()
  7649. {
  7650. result = CurrStepResult == 2 ? 2 : 1,
  7651. X = res.posX,
  7652. Y = res.posY,
  7653. PointCode = testName,
  7654. Data = Math.Round(lstTestData.Average(), 4),
  7655. StepName = processName,
  7656. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7657. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  7658. isAverage = true
  7659. });
  7660. PrintDataList(processName, testParam, LwValue, LwUpper, LwLower);
  7661. OnAutoRuning(new RunEventArgs(stepIndex, processName + ":检测失败", lstTestData, Math.Round(lstTestData.Average(), 2),
  7662. Math.Round(lstTestData.Max(), 2), Math.Round(lstTestData.Min(), 2), CurrStepResult > 0 ? 3 : 2, false));
  7663. }
  7664. }
  7665. }
  7666. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"失败:{res.resultInfo}"));
  7667. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测失败index:{res.index}:{res.resultInfo}");
  7668. }
  7669. //保存
  7670. if (confMgr.SysConfigParams.SizeBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeBigImag.SavePath))
  7671. {
  7672. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7673. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{model.StepInfo.Name}.bmp";
  7674. if (res.Himage != null)
  7675. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  7676. else
  7677. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  7678. }
  7679. }
  7680. catch (Exception ex)
  7681. {
  7682. Log($"{res.stepIndex + 1}-{res.processName}", $"单点检测回调处理异常 index:{res.index},ex={ex.Message}");
  7683. }
  7684. endEvent.Set();//roundIndex=0成功或失败线程返回
  7685. //---
  7686. if (res.Himage != null)
  7687. {
  7688. res.Himage.Dispose();
  7689. res.Himage = null;
  7690. }
  7691. else
  7692. {
  7693. API.DeleteFile(res.file_path);
  7694. }
  7695. }
  7696. });
  7697. //需等上面异步回调中的相对偏移校正完成再继续
  7698. if (!asynRun)
  7699. {
  7700. if (!endEvent.WaitOne(60000))
  7701. {
  7702. Log($"{stepIndex + 1}-{processName}", $"单点检测等待超时,忽略继续!", WarningEnum.Low);
  7703. return false;
  7704. }
  7705. }
  7706. return true;
  7707. }
  7708. #endregion
  7709. #region 比对处理
  7710. private bool SizeComp(int stepIndex, string processName, string EngineName, string gbxBmpPath, string picName, bool asynRun)
  7711. {
  7712. if (scannerCBmpQueue.Count < 1)
  7713. {
  7714. Log($"{stepIndex + 1}-{processName}", $"比对检测异常,无源图像!!", WarningEnum.Low);
  7715. return false;
  7716. }
  7717. var bmpCBmpQueue = scannerCBmpQueue.Dequeue();
  7718. Log($"{stepIndex + 1}-{processName}", $"开始比对检测,posX:{bmpCBmpQueue.PosX},posY:{bmpCBmpQueue.PosY},图像队列数量: {scannerCBmpQueue.Count}...");
  7719. //需要偏移校正,index=0时不能异步 //10,20,30... 
  7720. AutoResetEvent endEvent = new AutoResetEvent(false);
  7721. SizeLib.add(new SizeTask()
  7722. {
  7723. stepIndex = stepIndex,
  7724. processName = processName,
  7725. //sizeTag = sizeTag,
  7726. engineName = EngineName,
  7727. Himage = bmpCBmpQueue.Himage.Clone(),//bmp/file_path二选一,优先bmp
  7728. file_path = bmpCBmpQueue.Path,
  7729. drawingPagePath = gbxBmpPath,
  7730. posX = bmpCBmpQueue.PosX,
  7731. posY = bmpCBmpQueue.PosY,
  7732. index = 777,// 比对
  7733. ContoursAffineTrans1_Out = this.contoursAffineTrans1_Out,//只有777时才使用最近333输出的结果
  7734. finishEvent = (res) =>
  7735. {
  7736. try
  7737. {
  7738. //比对
  7739. if (res.index == 777)//比对
  7740. {
  7741. if (res.isSucceed)
  7742. {
  7743. //界面显示
  7744. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},图像比对:{(res.CompResult ? "通过" : "未通过")} "));
  7745. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对,index:{res.index}-{compBmpIndex},posX:{res.posX},posY:{res.posY},结果:{(res.CompResult ? "通过" : "未通过")}");
  7746. //
  7747. if (order.CompareResult < 2)
  7748. order.CompareResult = res.CompResult ? 1 : 2;
  7749. if (!res.CompResult)
  7750. {
  7751. //不合格
  7752. order.Qualified = false;
  7753. }
  7754. //更新比对看板 对比置零3
  7755. if (!res.CompResult)
  7756. SizeNGCnt++;
  7757. if (SizeNGCnt > 0)
  7758. 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));
  7759. //OnAutoRuning(new RunEventArgs(3, false, SizeNGCnt));
  7760. else
  7761. 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));
  7762. //OnAutoRuning(new RunEventArgs(3, true, SizeNGCnt));
  7763. if (!res.CompResult)
  7764. {
  7765. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对,未通过结果:{JsonConvert.SerializeObject(res.defectInfor2RestorationDesk)}");
  7766. //转为图纸上坐标位置
  7767. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  7768. {
  7769. //AddTextEvent($"{res.stepIndex + 1}-{res.processName}", $"转换到图纸后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
  7770. if (order.DefectInfoList == null)
  7771. order.DefectInfoList = new List<DefectInfo>();
  7772. foreach (var item in res.defectInfor2RestorationDeskPage)
  7773. order.DefectInfoList.Add(new DefectInfo()
  7774. {
  7775. Type = 1,
  7776. Code = item[3],
  7777. X = double.Parse(item[1]),
  7778. Y = double.Parse(item[2]),
  7779. ZXD = double.Parse(item[4]),
  7780. ModifyUserCode = userMgr.LoginUser.Code,
  7781. CreateUserCode = userMgr.LoginUser.Code,
  7782. });
  7783. }
  7784. //比对失败的图片 -- 用于修复台调用
  7785. Bitmap bmpCompareFailZoomImage = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.Zoom_Image_mat);
  7786. lstCompareFailZoomImage.Add(bmpCompareFailZoomImage);
  7787. if (confMgr.SysConfigParams.SizeRepairImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeRepairImag.SavePath))
  7788. {
  7789. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeRepairImag.SavePath,
  7790. new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7791. //path += $"Size_SN{order.SN}_I{res.index}_X{res.Defects_X}_Y{res.Defects_Y}_C0_{ model.StepInfo.Name}";
  7792. path += $"Size_SN{order.SN}_I{compBmpIndex}_X{res.posX}_Y{res.posY}_C0_{picName}";
  7793. lock (ImageSaveObj)
  7794. {
  7795. bmpCompareFailZoomImage.Save(path + ".bmp", ImageFormat.Bmp);
  7796. if (res.defectInfor2RestorationDesk != null && res.defectInfor2RestorationDesk.Count > 0)
  7797. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
  7798. }
  7799. }
  7800. //保存不良原图
  7801. if (confMgr.SysConfigParams.SizeNGImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.SizeNGImag.SavePath))
  7802. {
  7803. string path = Util.CreateSubDir(confMgr.SysConfigParams.SizeNGImag.SavePath,
  7804. new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7805. path += $"Size_SN{order.SN}_I{res.index}_X{res.posX}_Y{res.posY}_{picName}.bmp";
  7806. Log($"{res.stepIndex + 1}-{processName}", $"未通过图片保存:{path}");
  7807. if (res.Himage != null)
  7808. HOperatorSet.WriteImage(res.Himage, "bmp", 0, path);
  7809. else
  7810. API.CopyFile(res.file_path, path, false);//比.NET(File.Copy)更快
  7811. }
  7812. }
  7813. }
  7814. else
  7815. {
  7816. order.CompareResult = 2;
  7817. order.Qualified = false;
  7818. SizeNGCnt++;
  7819. OnAutoRuning(new RunEventArgs(res.stepIndex, $"图像比对失败,index:{res.index}-{compBmpIndex}.", new List<double>(), 0, SizeNGCnt, 0, 1, true));
  7820. //OnAutoRuning(new RunEventArgs(3, false, SizeNGCnt));
  7821. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"index:{res.index},图像比对失败!"));
  7822. Log($"{res.stepIndex + 1}-{res.processName}", $"图像比对失败,index:{res.index}-{compBmpIndex}.", WarningEnum.Low);
  7823. }
  7824. compBmpIndex++;
  7825. }
  7826. }
  7827. catch (Exception ex)
  7828. {
  7829. Log($"{res.stepIndex + 1}-{res.processName}", $"尺寸检测回调处理异常 index:{res.index},ex={ex.Message}");
  7830. }
  7831. endEvent.Set();//roundIndex=0成功或失败线程返回
  7832. //---
  7833. if (res.Himage != null)
  7834. {
  7835. res.Himage.Dispose();
  7836. res.Himage = null;
  7837. }
  7838. else
  7839. {
  7840. API.DeleteFile(res.file_path);
  7841. }
  7842. }
  7843. });
  7844. compBmpNum++;
  7845. //需等上面异步回调中的相对偏移校正完成再继续
  7846. if (!asynRun)
  7847. {
  7848. if (!endEvent.WaitOne(60000))
  7849. {
  7850. Log($"{stepIndex + 1}-{processName}", $"比对等待超时,忽略继续!", WarningEnum.Low);
  7851. return false;
  7852. }
  7853. }
  7854. return true;
  7855. }
  7856. #endregion
  7857. #region 缺陷处理
  7858. private bool DefectPicture(int stepIndex, string processName,SizeDefectProp param, string gbxBmpPath, Product md, string picName)
  7859. {
  7860. if (scannerGBmpQueue.Count < 1)
  7861. {
  7862. Log($"{stepIndex + 1}-{processName}", $"缺陷检测异常,无源图像!!", WarningEnum.Low);
  7863. return false;
  7864. }
  7865. var bmpLoc = scannerGBmpQueue.Dequeue();
  7866. Log($"{stepIndex + 1}-{processName}", $"开始缺陷检测,源图索引:{defectBmpNum},图像队列数量: {scannerGBmpQueue.Count}...");
  7867. //string[] aarCut_size = param.CutSize;
  7868. //string[] aarResize = processParam.Value<string>("Resize").Split(',');
  7869. //获取模型类型
  7870. string modeltp;
  7871. Classes tClasses = svcClasses.GetById(md.ClassesId);
  7872. if (tClasses.Name == "乳剂")
  7873. modeltp = "rj";
  7874. else
  7875. modeltp = "pt";
  7876. defectLib.add(new DefectTask()
  7877. {
  7878. stepIndex = stepIndex,
  7879. processName = processName,
  7880. modelType = modeltp,
  7881. drawingPagePath = gbxBmpPath,
  7882. //index = defectBmpNum++,
  7883. index = defectBmpNum,
  7884. bmp = bmpLoc.bmp.Clone(),
  7885. Xmm = bmpLoc.Xmm,
  7886. Ymm = bmpLoc.Ymm,
  7887. cut_size = new System.Drawing.Size(param.CutSize.Width, param.CutSize.Height),
  7888. resize = new System.Drawing.Size(param.Resize.Width, param.Resize.Height),
  7889. thresholds = param.Thresholds,
  7890. thresholdsClass = param.ThresholdsClass,
  7891. recAreaThreshold = getProductAreaThreshol(md), //qxName,面积; qxName,面积; qxName,面积;
  7892. finishEvent = (res) =>
  7893. {
  7894. if (res.isSucceed)
  7895. {
  7896. //界面显示
  7897. OnAutoRuning(new RunEventArgs(res.stepIndex, $"缺陷检测完成(源图索引:{res.index}),缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}",
  7898. new List<double>(), 1, 1, res.defectCount, 1, true));
  7899. //OnAutoRuning(new RunEventArgs(liStatocStepIndex,
  7900. // $"源图索引:{res.index},缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}"));
  7901. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测完成(源图索引:{res.index}),缺陷数:{res.defectCount},处理时间(ms):{string.Join("->", res.stopwatch.Select(i => i.ToString()).ToArray())}");
  7902. string path;
  7903. if (res.defectCount > 0)
  7904. {
  7905. //UI显示小图 (含统计缺陷类型数量)
  7906. AllDefectCount += res.informationList.Count;
  7907. showDefectSmallBmps(res.bmps_tag, res.bmps_cut, res.Xmm, res.Ymm, res.informationList);
  7908. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  7909. {
  7910. Log($"{res.stepIndex + 1}-{res.processName}", $"转换后坐标数据:{JsonConvert.SerializeObject(res.defectInfor2RestorationDeskPage)}");
  7911. if (order.DefectInfoList == null)
  7912. order.DefectInfoList = new List<DefectInfo>();
  7913. #if false
  7914. foreach (var item in res.defectInfor2RestorationDeskPage)
  7915. order.DefectInfoList.Add(new DefectInfo()
  7916. {
  7917. Type = 0,
  7918. Code = item[3],
  7919. X = double.Parse(item[1]),
  7920. Y = double.Parse(item[2]),
  7921. ZXD = double.Parse(item[4]),
  7922. Index = int.Parse(item[0]),
  7923. Area = item.Count>5?double.Parse(item[5]):0,
  7924. ModifyUserCode = UserMgr.LoginUser.Code,
  7925. CreateUserCode = UserMgr.LoginUser.Code,
  7926. });
  7927. #else
  7928. for (int i = 0; i < res.defectInfor2RestorationDeskPage.Count; i++)
  7929. {
  7930. double n;
  7931. order.DefectInfoList.Add(new DefectInfo()
  7932. {
  7933. Type = 0,
  7934. Code = res.defectInfor2RestorationDeskPage[i][3],
  7935. X = double.Parse(res.defectInfor2RestorationDeskPage[i][1]),
  7936. Y = double.Parse(res.defectInfor2RestorationDeskPage[i][2]),
  7937. ZXD = double.Parse(res.defectInfor2RestorationDeskPage[i][4]),
  7938. Index = int.Parse(res.defectInfor2RestorationDeskPage[i][0]),
  7939. Area = ((res.defectInfor2RestorationDesk[i].Count > 5 )&& (double.TryParse(res.defectInfor2RestorationDesk[i][5], out n))) ? double.Parse(res.defectInfor2RestorationDesk[i][5]) : 0,
  7940. ModifyUserCode = UserMgr.LoginUser.Code,
  7941. CreateUserCode = UserMgr.LoginUser.Code,
  7942. });
  7943. }
  7944. #endif
  7945. }
  7946. //保存原始大图
  7947. if (confMgr.SysConfigParams.DefectBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectBigImag.SavePath))
  7948. {
  7949. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7950. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{picName}";
  7951. lock (ImageSaveObj)
  7952. {
  7953. res.bmp.ImWrite(path + ".bmp");
  7954. //OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
  7955. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.informationList));
  7956. }
  7957. }
  7958. //保存小图
  7959. if (confMgr.SysConfigParams.DefectSmallImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectSmallImag.SavePath))
  7960. {
  7961. //2024-03-07 图片index计算
  7962. List<string> indexList = new List<string>();
  7963. if (res.defectInfor2RestorationDeskPage != null && res.defectInfor2RestorationDeskPage.Count > 0)
  7964. foreach (var item in res.defectInfor2RestorationDeskPage)
  7965. {
  7966. if (indexList.Count == 0)
  7967. indexList.Add(item[0]);
  7968. else
  7969. {
  7970. if (!indexList.Contains(item[0]))
  7971. indexList.Add(item[0]);
  7972. }
  7973. }
  7974. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectSmallImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7975. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_{picName}";
  7976. if (res.bmps_tag.Count() != indexList.Count)
  7977. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷图片张数和index对不上:{res.bmps_tag.Count()} - {indexList.Count}", WarningEnum.Low);
  7978. for (int i = 0; i < res.bmps_tag.Count(); i++)
  7979. {
  7980. lock (ImageSaveObj)
  7981. {
  7982. if (res.bmps_tag.Count() != indexList.Count)
  7983. res.bmps_tag[i].Save(path + $"_i{i}_{i}.bmp", ImageFormat.Bmp);
  7984. else
  7985. res.bmps_tag[i].Save(path + $"_i{i}_{indexList[i]}.bmp", ImageFormat.Bmp);
  7986. }
  7987. //res.bmps_tag[i].Save(path + $"_i{i}.bmp", ImageFormat.Bmp);
  7988. //res.bmps_tag[i].Save(path + $"{indexList[i]}.bmp", ImageFormat.Bmp);
  7989. }
  7990. }
  7991. //保存压缩大图 -- 用于修复台调用
  7992. if (confMgr.SysConfigParams.DefectRepairImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectRepairImag.SavePath))
  7993. {
  7994. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectRepairImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  7995. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{picName}";
  7996. lock (ImageSaveObj)
  7997. {
  7998. res.bmpCompress.ImWrite(path + ".bmp");
  7999. //OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmpCompress).Save(path + ".bmp", ImageFormat.Bmp);
  8000. File.WriteAllText(path + ".json", JsonConvert.SerializeObject(res.defectInfor2RestorationDesk));
  8001. }
  8002. }
  8003. }
  8004. else//没有缺陷
  8005. {
  8006. if (confMgr.SysConfigParams.SaveAllImg && confMgr.SysConfigParams.DefectBigImag.SavePath != "" && Directory.Exists(confMgr.SysConfigParams.DefectBigImag.SavePath))
  8007. {
  8008. path = Util.CreateSubDir(confMgr.SysConfigParams.DefectBigImag.SavePath, new List<string> { order.CreateTime.ToString("yyyyMMdd"), order.SN });
  8009. path += $"Defect_SN{order.SN}_I{res.index}_X{res.Xmm}_Y{res.Ymm}_C{res.defectCount}_{picName}";
  8010. lock (ImageSaveObj)
  8011. {
  8012. res.bmp.ImWrite(path + ".bmp");
  8013. //OpenCvSharp.Extensions.BitmapConverter.ToBitmap(res.bmp).Save(path + ".bmp", ImageFormat.Bmp);
  8014. }
  8015. }
  8016. }
  8017. }
  8018. else
  8019. {
  8020. OnAutoRuning(new RunEventArgs(res.stepIndex, $"缺陷检测失败:{res.resultInfo}", new List<double>(), 1, -1, -1, 1, true));
  8021. //OnAutoRuning(new RunEventArgs(liStatocStepIndex, $"失败:{res.resultInfo}"));
  8022. Log($"{res.stepIndex + 1}-{res.processName}", $"缺陷检测失败:{res.resultInfo}");
  8023. //暂停 这里不能暂停,stepIndex和scannerBmpQueue队列也不对了
  8024. }
  8025. defectBmpNumResult++;
  8026. foreach (var item in res.bmps_cut)
  8027. item.Dispose();
  8028. res.bmp.Dispose();
  8029. res.bmp = null;
  8030. res.bmps_tag = null;
  8031. if (res.bmpCompress != null)
  8032. {
  8033. res.bmpCompress.Dispose();
  8034. res.bmpCompress = null;
  8035. }
  8036. System.GC.Collect();
  8037. }
  8038. });
  8039. defectBmpNum++;
  8040. return true;
  8041. }
  8042. #endregion
  8043. #region 添加缺陷打印信息
  8044. private void AddDefectPrintInfo(SizeDefectProp defectParam)
  8045. {
  8046. if (defectParam.OpenPrint)
  8047. {
  8048. if (!string.IsNullOrEmpty(defectParam.ExcelDefectCount))
  8049. CurrPrintInfos.Add(new PrintInfo()
  8050. {
  8051. Type = 0,
  8052. IsValue = false,
  8053. PrintKey = defectParam.ExcelDefectCount,
  8054. PrintCode = "ExcelDefectCount",
  8055. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8056. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8057. });
  8058. if (!string.IsNullOrEmpty(defectParam.ExcelDKCount))
  8059. CurrPrintInfos.Add(new PrintInfo()
  8060. {
  8061. Type = 0,
  8062. IsValue = false,
  8063. PrintKey = defectParam.ExcelDKCount,
  8064. PrintCode = "ExcelDKCount",
  8065. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8066. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8067. });
  8068. if (!string.IsNullOrEmpty(defectParam.ExcelZWCount))
  8069. CurrPrintInfos.Add(new PrintInfo()
  8070. {
  8071. Type = 0,
  8072. IsValue = false,
  8073. PrintKey = defectParam.ExcelZWCount,
  8074. PrintCode = "ExcelZWCount",
  8075. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8076. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8077. });
  8078. if (!string.IsNullOrEmpty(defectParam.ExcelGSYCCount))
  8079. CurrPrintInfos.Add(new PrintInfo()
  8080. {
  8081. Type = 0,
  8082. IsValue = false,
  8083. PrintKey = defectParam.ExcelGSYCCount,
  8084. PrintCode = "ExcelGSYCCount",
  8085. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8086. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8087. });
  8088. if (!string.IsNullOrEmpty(defectParam.ExcelXWSCount))
  8089. CurrPrintInfos.Add(new PrintInfo()
  8090. {
  8091. Type = 0,
  8092. IsValue = false,
  8093. PrintKey = defectParam.ExcelXWSCount,
  8094. PrintCode = "ExcelXWSCount",
  8095. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8096. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8097. });
  8098. if (!string.IsNullOrEmpty(defectParam.ExcelQKCount))
  8099. CurrPrintInfos.Add(new PrintInfo()
  8100. {
  8101. Type = 0,
  8102. IsValue = false,
  8103. PrintKey = defectParam.ExcelQKCount,
  8104. PrintCode = "ExcelQKCount",
  8105. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8106. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8107. });
  8108. if (!string.IsNullOrEmpty(defectParam.ExcelZKCount))
  8109. CurrPrintInfos.Add(new PrintInfo()
  8110. {
  8111. Type = 0,
  8112. IsValue = false,
  8113. PrintKey = defectParam.ExcelZKCount,
  8114. PrintCode = "ExcelZKCount",
  8115. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8116. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8117. });
  8118. if (!string.IsNullOrEmpty(defectParam.ExcelPPCount))
  8119. CurrPrintInfos.Add(new PrintInfo()
  8120. {
  8121. Type = 0,
  8122. IsValue = false,
  8123. PrintKey = defectParam.ExcelPPCount,
  8124. PrintCode = "ExcelPPCount",
  8125. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8126. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8127. });
  8128. if (!string.IsNullOrEmpty(defectParam.ExcelHSCount))
  8129. CurrPrintInfos.Add(new PrintInfo()
  8130. {
  8131. Type = 0,
  8132. IsValue = false,
  8133. PrintKey = defectParam.ExcelHSCount,
  8134. PrintCode = "ExcelHSCount",
  8135. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8136. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8137. });
  8138. if (!string.IsNullOrEmpty(defectParam.ExcelYXCount))
  8139. CurrPrintInfos.Add(new PrintInfo()
  8140. {
  8141. Type = 0,
  8142. IsValue = false,
  8143. PrintKey = defectParam.ExcelYXCount,
  8144. PrintCode = "ExcelYXCount",
  8145. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8146. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8147. });
  8148. if (!string.IsNullOrEmpty(defectParam.ExcelXBCount))
  8149. CurrPrintInfos.Add(new PrintInfo()
  8150. {
  8151. Type = 0,
  8152. IsValue = false,
  8153. PrintKey = defectParam.ExcelXBCount,
  8154. PrintCode = "ExcelXBCount",
  8155. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8156. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8157. });
  8158. if (!string.IsNullOrEmpty(defectParam.ExcelSXCount))
  8159. CurrPrintInfos.Add(new PrintInfo()
  8160. {
  8161. Type = 0,
  8162. IsValue = false,
  8163. PrintKey = defectParam.ExcelSXCount,
  8164. PrintCode = "ExcelSXCount",
  8165. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8166. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8167. });
  8168. if (!string.IsNullOrEmpty(defectParam.ExcelDSCount))
  8169. CurrPrintInfos.Add(new PrintInfo()
  8170. {
  8171. Type = 0,
  8172. IsValue = false,
  8173. PrintKey = defectParam.ExcelDSCount,
  8174. PrintCode = "ExcelDSCount",
  8175. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8176. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8177. });
  8178. if (!string.IsNullOrEmpty(defectParam.ExcelGSDLCount))
  8179. CurrPrintInfos.Add(new PrintInfo()
  8180. {
  8181. Type = 0,
  8182. IsValue = false,
  8183. PrintKey = defectParam.ExcelGSDLCount,
  8184. PrintCode = "ExcelGSDLCount",
  8185. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8186. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8187. });
  8188. if (!string.IsNullOrEmpty(defectParam.ExcelCJDKCount))
  8189. CurrPrintInfos.Add(new PrintInfo()
  8190. {
  8191. Type = 0,
  8192. IsValue = false,
  8193. PrintKey = defectParam.ExcelCJDKCount,
  8194. PrintCode = "ExcelCJDKCount",
  8195. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8196. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8197. });
  8198. }
  8199. if (defectParam.OpenPrintLabel)
  8200. {
  8201. if (!string.IsNullOrEmpty(defectParam.LabelDefectCount))
  8202. CurrPrintInfos.Add(new PrintInfo()
  8203. {
  8204. Type = 1,
  8205. IsValue = false,
  8206. PrintKey = defectParam.LabelDefectCount,
  8207. PrintCode = "LabelDefectCount",
  8208. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8209. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8210. });
  8211. if (!string.IsNullOrEmpty(defectParam.LabelDKCount))
  8212. CurrPrintInfos.Add(new PrintInfo()
  8213. {
  8214. Type = 1,
  8215. IsValue = false,
  8216. PrintKey = defectParam.LabelDKCount,
  8217. PrintCode = "LabelDKCount",
  8218. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8219. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8220. });
  8221. if (!string.IsNullOrEmpty(defectParam.LabelZWCount))
  8222. CurrPrintInfos.Add(new PrintInfo()
  8223. {
  8224. Type = 1,
  8225. IsValue = false,
  8226. PrintKey = defectParam.LabelZWCount,
  8227. PrintCode = "LabelZWCount",
  8228. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8229. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8230. });
  8231. if (!string.IsNullOrEmpty(defectParam.LabelGSYCCount))
  8232. CurrPrintInfos.Add(new PrintInfo()
  8233. {
  8234. Type = 1,
  8235. IsValue = false,
  8236. PrintKey = defectParam.LabelGSYCCount,
  8237. PrintCode = "LabelGSYCCount",
  8238. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8239. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8240. });
  8241. if (!string.IsNullOrEmpty(defectParam.LabelXWSCount))
  8242. CurrPrintInfos.Add(new PrintInfo()
  8243. {
  8244. Type = 1,
  8245. IsValue = false,
  8246. PrintKey = defectParam.LabelXWSCount,
  8247. PrintCode = "LabelXWSCount",
  8248. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8249. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8250. });
  8251. if (!string.IsNullOrEmpty(defectParam.LabelQKCount))
  8252. CurrPrintInfos.Add(new PrintInfo()
  8253. {
  8254. Type = 1,
  8255. IsValue = false,
  8256. PrintKey = defectParam.LabelQKCount,
  8257. PrintCode = "LabelQKCount",
  8258. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8259. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8260. });
  8261. if (!string.IsNullOrEmpty(defectParam.LabelZKCount))
  8262. CurrPrintInfos.Add(new PrintInfo()
  8263. {
  8264. Type = 1,
  8265. IsValue = false,
  8266. PrintKey = defectParam.LabelZKCount,
  8267. PrintCode = "LabelZKCount",
  8268. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8269. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8270. });
  8271. if (!string.IsNullOrEmpty(defectParam.LabelPPCount))
  8272. CurrPrintInfos.Add(new PrintInfo()
  8273. {
  8274. Type = 1,
  8275. IsValue = false,
  8276. PrintKey = defectParam.LabelPPCount,
  8277. PrintCode = "LabelPPCount",
  8278. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8279. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8280. });
  8281. if (!string.IsNullOrEmpty(defectParam.LabelHSCount))
  8282. CurrPrintInfos.Add(new PrintInfo()
  8283. {
  8284. Type = 1,
  8285. IsValue = false,
  8286. PrintKey = defectParam.LabelHSCount,
  8287. PrintCode = "LabelHSCount",
  8288. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8289. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8290. });
  8291. if (!string.IsNullOrEmpty(defectParam.LabelYXCount))
  8292. CurrPrintInfos.Add(new PrintInfo()
  8293. {
  8294. Type = 1,
  8295. IsValue = false,
  8296. PrintKey = defectParam.LabelYXCount,
  8297. PrintCode = "LabelYXCount",
  8298. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8299. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8300. });
  8301. if (!string.IsNullOrEmpty(defectParam.LabelXBCount))
  8302. CurrPrintInfos.Add(new PrintInfo()
  8303. {
  8304. Type = 1,
  8305. IsValue = false,
  8306. PrintKey = defectParam.LabelXBCount,
  8307. PrintCode = "LabelXBCount",
  8308. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8309. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8310. });
  8311. if (!string.IsNullOrEmpty(defectParam.LabelSXCount))
  8312. CurrPrintInfos.Add(new PrintInfo()
  8313. {
  8314. Type = 1,
  8315. IsValue = false,
  8316. PrintKey = defectParam.LabelSXCount,
  8317. PrintCode = "LabelSXCount",
  8318. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8319. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8320. });
  8321. if (!string.IsNullOrEmpty(defectParam.LabelDSCount))
  8322. CurrPrintInfos.Add(new PrintInfo()
  8323. {
  8324. Type = 1,
  8325. IsValue = false,
  8326. PrintKey = defectParam.LabelDSCount,
  8327. PrintCode = "LabelDSCount",
  8328. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8329. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8330. });
  8331. if (!string.IsNullOrEmpty(defectParam.LabelGSDLCount))
  8332. CurrPrintInfos.Add(new PrintInfo()
  8333. {
  8334. Type = 1,
  8335. IsValue = false,
  8336. PrintKey = defectParam.LabelGSDLCount,
  8337. PrintCode = "LabelGSDLCount",
  8338. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8339. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8340. });
  8341. if (!string.IsNullOrEmpty(defectParam.LabelCJDKCount))
  8342. CurrPrintInfos.Add(new PrintInfo()
  8343. {
  8344. Type = 1,
  8345. IsValue = false,
  8346. PrintKey = defectParam.LabelCJDKCount,
  8347. PrintCode = "LabelCJDKCount",
  8348. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  8349. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  8350. });
  8351. }
  8352. }
  8353. #endregion
  8354. #endregion
  8355. #region 日志图片删除
  8356. #region 文件删除
  8357. public void DelectPictureFile()
  8358. {
  8359. //删除文件
  8360. Task.Factory.StartNew(() =>
  8361. {
  8362. //图片
  8363. if (confMgr.SysConfigParams.DefectBigImag.AutoDelete)
  8364. statusMgr.DeleteFiles(confMgr.SysConfigParams.DefectBigImag.SavePath, confMgr.SysConfigParams.DefectBigImag.AutoDeleteDays, true);
  8365. if (confMgr.SysConfigParams.DefectSmallImag.AutoDelete)
  8366. statusMgr.DeleteFiles(confMgr.SysConfigParams.DefectSmallImag.SavePath, confMgr.SysConfigParams.DefectSmallImag.AutoDeleteDays, true);
  8367. if (confMgr.SysConfigParams.DefectRepairImag.AutoDelete)
  8368. statusMgr.DeleteFiles(confMgr.SysConfigParams.DefectRepairImag.SavePath, confMgr.SysConfigParams.DefectRepairImag.AutoDeleteDays, true);
  8369. if (confMgr.SysConfigParams.SizeBigImag.AutoDelete)
  8370. statusMgr.DeleteFiles(confMgr.SysConfigParams.SizeBigImag.SavePath, confMgr.SysConfigParams.SizeBigImag.AutoDeleteDays, true);
  8371. if (confMgr.SysConfigParams.SizeNGImag.AutoDelete)
  8372. statusMgr.DeleteFiles(confMgr.SysConfigParams.SizeNGImag.SavePath, confMgr.SysConfigParams.SizeNGImag.AutoDeleteDays, true);
  8373. if (confMgr.SysConfigParams.SizeRepairImag.AutoDelete)
  8374. statusMgr.DeleteFiles(confMgr.SysConfigParams.SizeRepairImag.SavePath, confMgr.SysConfigParams.SizeRepairImag.AutoDeleteDays, true);
  8375. //日志
  8376. if (confMgr.SysConfigParams.AutoDeleteLog)
  8377. statusMgr.DeleteFiles(confMgr.SysConfigParams.LogPath, confMgr.SysConfigParams.AutoDeleteLogData, true);
  8378. });
  8379. }
  8380. #endregion
  8381. #endregion
  8382. #region 系统事件显示回调
  8383. /// <summary>
  8384. /// 初始化回调
  8385. /// </summary>
  8386. /// <param name="sender"></param>
  8387. /// <param name="e"></param>
  8388. public delegate void InitEventHandler(Object sender, InitEventArgs e);
  8389. public event InitEventHandler InitRuning;
  8390. protected virtual void OnInitRuning(InitEventArgs e)
  8391. {
  8392. if (null != InitRuning)
  8393. {
  8394. InitRuning(this, e);
  8395. }
  8396. }
  8397. /// <summary>
  8398. /// 流程回调
  8399. /// </summary>
  8400. /// <param name="sender"></param>
  8401. /// <param name="e"></param>
  8402. public delegate void RunEventHandler(Object sender, RunEventArgs e);
  8403. public event RunEventHandler AutoRuning;
  8404. protected virtual void OnAutoRuning(RunEventArgs e)
  8405. {
  8406. if (null != AutoRuning)
  8407. {
  8408. AutoRuning(this, e);
  8409. }
  8410. }
  8411. /// <summary>
  8412. /// 显图回调
  8413. /// </summary>
  8414. /// <param name="sender"></param>
  8415. /// <param name="e"></param>
  8416. public delegate void ImgEventHandler(Object sender, ImgEventArgs e);
  8417. public event ImgEventHandler AutoShowImg;
  8418. protected virtual void OnAutoShowImg(ImgEventArgs e)
  8419. {
  8420. if (null != AutoShowImg)
  8421. {
  8422. AutoShowImg(this, e);
  8423. }
  8424. }
  8425. /// <summary>
  8426. /// 主窗体回调
  8427. /// </summary>
  8428. /// <param name="sender"></param>
  8429. /// <param name="e"></param>
  8430. public delegate void MainEventHandler(Object sender, MainEventArgs e);
  8431. public event MainEventHandler MainRuning;
  8432. protected virtual void OnMainRuning(MainEventArgs e)
  8433. {
  8434. if (null != MainRuning)
  8435. {
  8436. MainRuning(this, e);
  8437. }
  8438. }
  8439. private void showDefectSmallBmps(Bitmap[] bmps, Mat[] bmps_cut, double Xmm, double Ymm, List<Dictionary<int, List<string>[]>> info)
  8440. {
  8441. OnAutoShowImg(new ImgEventArgs(bmps, bmps_cut, Xmm, Ymm, info));
  8442. }
  8443. #endregion
  8444. #region 界面显示
  8445. public static void showRowNum_onDataGrid_RowPostPaint(DataGridView dgv, object sender, DataGridViewRowPostPaintEventArgs e)
  8446. {
  8447. Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, dgv.RowHeadersWidth - 4, e.RowBounds.Height);
  8448. TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), dgv.RowHeadersDefaultCellStyle.Font, rectangle, dgv.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
  8449. }
  8450. /// <summary>
  8451. /// IO二进制数据格式化到8位 XXXX10X0
  8452. /// </summary>
  8453. /// <param name="datas"></param>
  8454. /// <returns></returns>
  8455. public static string[] IODataFormatBinaryStr(string[] datas, bool clone, char defaultPadChar = 'X')
  8456. {
  8457. string[] datas2 = new string[datas.Length];
  8458. for (int i = 0; i < datas.Length; i++)
  8459. {
  8460. if (clone)
  8461. {
  8462. datas2[i] = datas[i].Replace(" ", "");
  8463. if (datas2[i].Length > 8)
  8464. datas2[i] = datas2[i].Substring(datas2[i].Length - 8);
  8465. else if (datas2[i].Length < 8)
  8466. datas2[i] = datas2[i].PadLeft(8, defaultPadChar);
  8467. }
  8468. else
  8469. {
  8470. datas[i] = datas[i].Replace(" ", "");
  8471. if (datas[i].Length > 8)
  8472. datas[i] = datas[i].Substring(datas[i].Length - 8);
  8473. else if (datas[i].Length < 8)
  8474. datas[i] = datas[i].PadLeft(8, defaultPadChar);
  8475. datas2 = datas;
  8476. }
  8477. }
  8478. return datas2;
  8479. }
  8480. /// <summary>
  8481. ///
  8482. /// </summary>
  8483. /// <param name="op_show_list">[XXHL XXXX,XXXX XXXX,...]</param>
  8484. /// <param name="currIoDatas">[byte,byte,byte,byte]</param>
  8485. /// <returns></returns>
  8486. public static bool compareIOInput(string[] op_show_list, byte[] currIoDatas)
  8487. {
  8488. int isok = 0;//1-true 2-false
  8489. string IN_OP_SHOW;
  8490. for (int i = 0; i < currIoDatas.Length; i++)
  8491. {
  8492. IN_OP_SHOW = op_show_list[i].Replace(" ", "").PadLeft(8, 'X');
  8493. if (IN_OP_SHOW.IndexOf('H') < 0 && IN_OP_SHOW.IndexOf('L') < 0)
  8494. continue;
  8495. for (int j = 7; j >= 0; j--)
  8496. {
  8497. byte bit = (byte)(1 << 7 - j);
  8498. if (IN_OP_SHOW[j] == 'H')
  8499. {
  8500. if ((bit & currIoDatas[i]) > 0)
  8501. isok = 1;
  8502. else
  8503. {
  8504. isok = 2;
  8505. break;
  8506. }
  8507. }
  8508. else if (IN_OP_SHOW[j] == 'L')
  8509. {
  8510. if ((currIoDatas[i] ^ (currIoDatas[i] | bit)) > 0)
  8511. isok = 1;
  8512. else
  8513. {
  8514. isok = 2;
  8515. break;
  8516. }
  8517. }
  8518. }
  8519. //已经不符
  8520. if (isok == 2) break;
  8521. }
  8522. //
  8523. return isok == 1;
  8524. }
  8525. #endregion
  8526. #region 硬盘检测
  8527. public static bool CheckDisk(IWin32Window owner, int max = 10)
  8528. {
  8529. string path = ConfMgr.Instance.SysConfigParams.DefectBigImag.SavePath;
  8530. string volume = path.Substring(0, path.IndexOf(':'));
  8531. long freespace = DiskAPI.GetHardDiskSpace(volume);
  8532. if (freespace < max)
  8533. {
  8534. string tip = $"当前{volume}硬盘容量:{freespace}GB,小于{max}GB。注意清理!!";
  8535. FrmDialog.ShowDialog(owner, tip, "警告", true);
  8536. return false;
  8537. }
  8538. return true;
  8539. }
  8540. #endregion
  8541. #region 自动聚焦
  8542. public bool AutoFocus(double FocusStep, double DirStep, int waitTime, int Timeout)
  8543. {
  8544. DateTime dt;
  8545. double step = FocusStep;
  8546. double dir_step = DirStep;
  8547. int axisno = (int)AxisName.Axis3;
  8548. double z = GetAxisPosValueMM(axisno);
  8549. double mean = 0;
  8550. double z_hpos = 0;
  8551. int cnt = 0;
  8552. int dir = 0;
  8553. DateTime alldt = DateTime.Now;
  8554. Yolo_Class yolo = new Yolo_Class();
  8555. //寻找方向
  8556. dt = DateTime.Now;
  8557. while (true)
  8558. {
  8559. double pos = GetAxisPosValueMM(axisno);
  8560. camDevFront.ClearImageQueue();
  8561. Acquisition acq = camDevFront.Snap(1, 5000);
  8562. if (acq.GrabStatus == "GrabPass")
  8563. {
  8564. //显示
  8565. OnAutoRuning(new RunEventArgs(0, acq.Image));
  8566. yolo.FocusDirec(acq.Image.CopyObj(1, -1), ref dir, ref mean, ref z_hpos);
  8567. cnt++;
  8568. if ((cnt > 2) && (dir != 0))
  8569. {
  8570. Log("自动找方向", $"步进次数:{cnt},位置:{pos}, 反馈方向:{dir}, 反馈位置:{z_hpos}, 步进:{dir_step}");
  8571. break;
  8572. }
  8573. VelocityCurveParams velocityCurve = new VelocityCurveParams(100, 100, 5, 100, 0, 1000);
  8574. //axisDev.MoveAbsValue(axisno, velocityCurve, z - cnt * dir_step);
  8575. if (cnt == 1)
  8576. {
  8577. mean = 0;
  8578. Log("自动找方向", $"步进次数:{cnt},位置:{pos}, mean:{mean}, 反馈方向:{dir}, 反馈位置:{z_hpos}");
  8579. axisDev.MoveAbsValue(axisno, velocityCurve, z_hpos);
  8580. axisDev.CheckDone(axisno, 20);
  8581. }
  8582. else
  8583. {
  8584. Log("自动找方向", $"步进次数:{cnt},位置:{pos}, mean:{mean}, 反馈方向:{dir}, 反馈位置:{z_hpos}, 步进:{dir_step}");
  8585. axisDev.MoveAbsValue(axisno, velocityCurve, pos - dir_step);
  8586. axisDev.CheckDone(axisno, 20);
  8587. }
  8588. //Log("自动找方向", $"步进次数:{cnt},位置:{z_hpos - cnt * dir_step}, 反馈:{dir}");
  8589. }
  8590. else
  8591. {
  8592. Log("自动找方向", $"拍照失败!");
  8593. return false;
  8594. }
  8595. if((DateTime.Now - dt).TotalMilliseconds > Timeout)
  8596. {
  8597. return false;
  8598. }
  8599. Thread.Sleep(waitTime);
  8600. }
  8601. cnt = 0;
  8602. mean = 0;
  8603. z = GetAxisPosValueMM(axisno);
  8604. //dt = DateTime.Now;
  8605. //聚焦
  8606. while (true)
  8607. {
  8608. double pos = GetAxisPosValueMM(axisno);
  8609. camDevFront.ClearImageQueue();
  8610. Acquisition acq = camDevFront.Snap(1, 1000);
  8611. if (acq.GrabStatus == "GrabPass")
  8612. {
  8613. //显示
  8614. OnAutoRuning(new RunEventArgs(0, acq.Image));
  8615. yolo.Focus(acq.Image.CopyObj(1, -1), step, ref dir, ref z, ref mean);
  8616. cnt++;
  8617. Log("自动聚焦", $"方向:{dir},下次目标位置:{z},次数:{cnt},反馈:{mean},Z轴当前实际位置:{pos}");
  8618. if (mean == 9999)
  8619. {
  8620. break;
  8621. }
  8622. VelocityCurveParams velocityCurve = new VelocityCurveParams(100, 100, 5, 100, 0, 1000);
  8623. axisDev.MoveAbsValue(axisno, velocityCurve, z);
  8624. axisDev.CheckDone(axisno, 20);
  8625. if ((DateTime.Now - alldt).TotalMilliseconds > Timeout)
  8626. {
  8627. return false;
  8628. }
  8629. }
  8630. else
  8631. {
  8632. Log("自动找方向", $"拍照失败!");
  8633. return false;
  8634. }
  8635. if ((DateTime.Now - alldt).TotalMilliseconds > Timeout)
  8636. {
  8637. return false;
  8638. }
  8639. }
  8640. return true;
  8641. }
  8642. #endregion
  8643. #region 打印
  8644. /// <summary>
  8645. /// 打印数据
  8646. /// </summary>
  8647. /// <param name="printerType"></param>
  8648. /// <param name="printerName"></param>
  8649. /// <param name="printerTemp"></param>
  8650. /// <param name="data"></param>
  8651. /// <param name="model"></param>
  8652. /// <returns></returns>
  8653. public bool PrintFileData(PrinterType printerType, string printerName, string printerTemp, Dictionary<string, string> data, Product model)
  8654. {
  8655. bool ret = true;
  8656. try
  8657. {
  8658. //Log("标签打印", $"打印机:{printerName}, 模板路径={printerTemp}");
  8659. if (printerType == PrinterType.Label)
  8660. {
  8661. if (!printControl.BarTenderOpenFile(printerTemp))
  8662. ret = false;
  8663. }
  8664. else if (printerType == PrinterType.Excel)
  8665. {
  8666. if (!printControl.ExcelOpenFile(printerTemp))
  8667. ret = false;
  8668. }
  8669. Dictionary<string, string> printData = new Dictionary<string, string>();
  8670. if (ret)
  8671. {
  8672. if (data != null)
  8673. {
  8674. foreach (var item in data)
  8675. {
  8676. string value = "";
  8677. foreach (var s in System.Enum.GetValues(typeof(PrintDataEnum)))
  8678. {
  8679. PrintDataEnum dataEnum = (PrintDataEnum)s;
  8680. if (dataEnum.GetDescription() == item.Value)
  8681. {
  8682. switch (dataEnum)
  8683. {
  8684. case PrintDataEnum.BatchId:
  8685. value = order.BatchId;
  8686. break;
  8687. case PrintDataEnum.CompareResult:
  8688. value = order.CompareResult == 0 ? "未比对" : order.CompareResult == 1 ? "OK" : "NG";
  8689. break;
  8690. case PrintDataEnum.Qualified:
  8691. value = order.Qualified ? "合格" : "不合格";
  8692. break;
  8693. case PrintDataEnum.OrderCode:
  8694. value = order.OrderCode;
  8695. break;
  8696. case PrintDataEnum.OrderName:
  8697. if (model != null)
  8698. value = model.Name;
  8699. else
  8700. value = "No Find";
  8701. break;
  8702. case PrintDataEnum.SN:
  8703. value = order.SN;
  8704. break;
  8705. case PrintDataEnum.DetectOrder:
  8706. value = order.DetectOrder;
  8707. break;
  8708. case PrintDataEnum.Time:
  8709. value = order.CreateTime.ToString("yyyy/MM/dd HH:mm");
  8710. break;
  8711. case PrintDataEnum.OperatorName:
  8712. value = userMgr.LoginUser.Name;
  8713. break;
  8714. case PrintDataEnum.TensionValue:
  8715. value = order.TensionValue.ToString("0.000");
  8716. break;
  8717. case PrintDataEnum.HeightValue:
  8718. value = order.HeightValue.ToString("0.000");
  8719. break;
  8720. case PrintDataEnum.LineWidthValue:
  8721. value = order.LineWidthValue.ToString("0.000");
  8722. break;
  8723. case PrintDataEnum.PTValue:
  8724. value = order.PTValue.ToString("0.0000");
  8725. break;
  8726. case PrintDataEnum.XPTValue:
  8727. value = order.XPTValue.ToString("0.0000");
  8728. break;
  8729. case PrintDataEnum.FLineWidthValue:
  8730. value = order.FLineWidthValue.ToString("0.000");
  8731. break;
  8732. case PrintDataEnum.MGridIntervalValue:
  8733. value = order.MGridIntervalValue.ToString("0.0000");
  8734. break;
  8735. case PrintDataEnum.MGridWidthValue:
  8736. value = order.MGridWidthValue.ToString("0.0000");
  8737. break;
  8738. case PrintDataEnum.MGridSpreadValue:
  8739. value = order.MGridSpreadValue.ToString("0.0000");
  8740. break;
  8741. case PrintDataEnum.FGridSpreadValue:
  8742. value = order.FGridSpreadValue.ToString("0.0000");
  8743. break;
  8744. case PrintDataEnum.BackPoleWidthValue:
  8745. value = order.BackPoleWidthValue.ToString("0.000");
  8746. break;
  8747. case PrintDataEnum.MGridLengthValue:
  8748. value = order.MGridLengthValue.ToString("0.0000");
  8749. break;
  8750. case PrintDataEnum.MarkXDisValue:
  8751. value = order.MarkXDisValue.ToString("0.0000");
  8752. break;
  8753. case PrintDataEnum.MarkYDisValue:
  8754. value = order.MarkYDisValue.ToString("0.0000");
  8755. break;
  8756. case PrintDataEnum.ForkLengthValue:
  8757. value = order.ForkLengthValue.ToString("0.0000");
  8758. break;
  8759. case PrintDataEnum.ForkWidthValue:
  8760. value = order.ForkWidthValue.ToString("0.000");
  8761. break;
  8762. case PrintDataEnum.ForkDisValue:
  8763. value = order.ForkDisValue.ToString("0.0000");
  8764. break;
  8765. case PrintDataEnum.ChilopodLengthValue:
  8766. value = order.ChilopodLengthValue.ToString("0.0000");
  8767. break;
  8768. case PrintDataEnum.ChilopodWidthValue:
  8769. value = order.ChilopodWidthValue.ToString("0.000");
  8770. break;
  8771. case PrintDataEnum.ShardingDisValue:
  8772. value = order.ShardingDisValue.ToString("0.0000");
  8773. break;
  8774. case PrintDataEnum.WeldingSpotDisValue:
  8775. value = order.WeldingSpotDisValue.ToString("0.0000");
  8776. break;
  8777. case PrintDataEnum.WeldingSpotLengthValue:
  8778. value = order.WeldingSpotLengthValue.ToString("0.0000");
  8779. break;
  8780. case PrintDataEnum.WeldingSpotWidthValue:
  8781. value = order.WeldingSpotWidthValue.ToString("0.0000");
  8782. break;
  8783. case PrintDataEnum.TensionValueLimit:
  8784. if (model != null)
  8785. value = $"上限:{model.TensionBaseValue + model.TensionUpFloatValue}\r\n下限:{model.TensionBaseValue - model.TensionDownFloatValue}";
  8786. else
  8787. value = "No Find";
  8788. break;
  8789. case PrintDataEnum.HeightValueLimit:
  8790. if (model != null)
  8791. value = $"上限:{model.HeightBaseValue + model.HeightUpFloatValue}\r\n下限:{model.HeightBaseValue - model.HeightDownFloatValue}";
  8792. else
  8793. value = "No Find";
  8794. break;
  8795. case PrintDataEnum.LineWidthValueLimit:
  8796. if (model != null)
  8797. value = $"上限:{model.LineWidthBaseValue + model.LineWidthUpFloatValue}\r\n下限:{model.LineWidthBaseValue - model.LineWidthDownFloatValue}";
  8798. else
  8799. value = "No Find";
  8800. break;
  8801. case PrintDataEnum.PTValueLimit:
  8802. if (model != null)
  8803. value = $"上限:{model.PTBaseValue + model.PTUpFloatValue}\r\n下限:{model.PTBaseValue - model.PTUpFloatValue}";
  8804. else
  8805. value = "No Find";
  8806. break;
  8807. case PrintDataEnum.XPTValueLimit:
  8808. if (model != null)
  8809. value = $"上限:{model.PTXBaseValue + model.PTXUpFloatValue}\r\n下限:{model.PTXBaseValue - model.PTXUpFloatValue}";
  8810. else
  8811. value = "No Find";
  8812. break;
  8813. case PrintDataEnum.FLineWidthValueLimit:
  8814. if (model != null)
  8815. value = $"上限:{model.FLineWidthBaseValue + model.FLineWidthUpFloatValue}\r\n下限:{model.FLineWidthBaseValue - model.FLineWidthDownFloatValue}";
  8816. else
  8817. value = "No Find";
  8818. break;
  8819. case PrintDataEnum.MGridIntervalValueLimit:
  8820. if (model != null)
  8821. value = $"上限:{model.MGridIntervalBaseValue + model.MGridIntervalUpFloatValue}\r\n下限:{model.MGridIntervalBaseValue - model.MGridIntervalDownFloatValue}";
  8822. else
  8823. value = "No Find";
  8824. break;
  8825. case PrintDataEnum.MGridWidthValueLimit:
  8826. if (model != null)
  8827. value = $"上限:{model.MGridWidthBaseValue + model.MGridWidthUpFloatValue}\r\n下限:{model.MGridWidthBaseValue - model.MGridWidthDownFloatValue}";
  8828. else
  8829. value = "No Find";
  8830. break;
  8831. case PrintDataEnum.MGridSpreadValueLimit:
  8832. if (model != null)
  8833. value = $"上限:{model.MGridSpreadBaseValue + model.MGridSpreadUpFloatValue}\r\n下限:{model.MGridSpreadBaseValue - model.MGridSpreadDownFloatValue}";
  8834. else
  8835. value = "No Find";
  8836. break;
  8837. case PrintDataEnum.FGridSpreadValueLimit:
  8838. if (model != null)
  8839. value = $"上限:{model.FGridSpreadBaseValue + model.FGridSpreadUpFloatValue}\r\n下限:{model.FGridSpreadBaseValue - model.FGridSpreadDownFloatValue}";
  8840. else
  8841. value = "No Find";
  8842. break;
  8843. case PrintDataEnum.BackPoleWidthValueLimit:
  8844. if (model != null)
  8845. value = $"上限:{model.BackPoleWidthBaseValue + model.BackPoleWidthUpFloatValue}\r\n下限:{model.BackPoleWidthBaseValue - model.BackPoleWidthDownFloatValue}";
  8846. else
  8847. value = "No Find";
  8848. break;
  8849. case PrintDataEnum.MGridLengthValueLimit:
  8850. if (model != null)
  8851. value = $"上限:{model.MGridLengthBaseValue + model.MGridLengthUpFloatValue}\r\n下限:{model.MGridLengthBaseValue - model.MGridLengthDownFloatValue}";
  8852. else
  8853. value = "No Find";
  8854. break;
  8855. case PrintDataEnum.MarkXDisValueLimit:
  8856. if (model != null)
  8857. value = $"上限:{model.MarkXDisBaseValue + model.MarkXDisUpFloatValue}\r\n下限:{model.MarkXDisBaseValue - model.MarkXDisDownFloatValue}";
  8858. else
  8859. value = "No Find";
  8860. break;
  8861. case PrintDataEnum.MarkYDisValueLimit:
  8862. if (model != null)
  8863. value = $"上限:{model.MarkYDisBaseValue + model.MarkYDisUpFloatValue}\r\n下限:{model.MarkYDisBaseValue - model.MarkYDisDownFloatValue}";
  8864. else
  8865. value = "No Find";
  8866. break;
  8867. case PrintDataEnum.ForkLengthValueLimit:
  8868. if (model != null)
  8869. value = $"上限:{model.ForkLengthBaseValue + model.ForkLengthBaseValue}\r\n下限:{model.ForkLengthBaseValue - model.ForkLengthDownFloatValue}";
  8870. else
  8871. value = "No Find";
  8872. break;
  8873. case PrintDataEnum.ForkWidthValueLimit:
  8874. if (model != null)
  8875. value = $"上限:{model.ForkWidthBaseValue + model.ForkWidthUpFloatValue}\r\n下限:{model.ForkWidthBaseValue - model.ForkWidthDownFloatValue}";
  8876. else
  8877. value = "No Find";
  8878. break;
  8879. case PrintDataEnum.ForkDisValueLimit:
  8880. if (model != null)
  8881. value = $"上限:{model.ForkDisBaseValue + model.ForkDisUpFloatValue}\r\n下限:{model.ForkDisBaseValue - model.ForkDisDownFloatValue}";
  8882. else
  8883. value = "No Find";
  8884. break;
  8885. case PrintDataEnum.ChilopodLengthValueLimit:
  8886. if (model != null)
  8887. value = $"上限:{model.ChilopodLengthBaseValue + model.ChilopodLengthUpFloatValue}\r\n下限:{model.ChilopodLengthBaseValue - model.ChilopodLengthDownFloatValue}";
  8888. else
  8889. value = "No Find";
  8890. break;
  8891. case PrintDataEnum.ChilopodWidthValueLimit:
  8892. if (model != null)
  8893. value = $"上限:{model.ChilopodWidthBaseValue + model.ChilopodWidthUpFloatValue}\r\n下限:{model.ChilopodWidthBaseValue - model.ChilopodWidthDownFloatValue}";
  8894. else
  8895. value = "No Find";
  8896. break;
  8897. case PrintDataEnum.ShardingDisValueLimit:
  8898. if (model != null)
  8899. value = $"上限:{model.ShardingDisBaseValue + model.ShardingDisUpFloatValue}\r\n下限:{model.ShardingDisBaseValue - model.ShardingDisDownFloatValue}";
  8900. else
  8901. value = "No Find";
  8902. break;
  8903. case PrintDataEnum.WeldingSpotDisValueLimit:
  8904. if (model != null)
  8905. value = $"上限:{model.WeldingSpotDisBaseValue + model.WeldingSpotDisUpFloatValue}\r\n下限:{model.WeldingSpotDisBaseValue - model.WeldingSpotDisDownFloatValue}";
  8906. else
  8907. value = "No Find";
  8908. break;
  8909. case PrintDataEnum.WeldingSpotLengthValueLimit:
  8910. if (model != null)
  8911. value = $"上限:{model.WeldingSpotLengthBaseValue + model.WeldingSpotLengthUpFloatValue}\r\n下限:{model.WeldingSpotLengthBaseValue - model.WeldingSpotLengthDownFloatValue}";
  8912. else
  8913. value = "No Find";
  8914. break;
  8915. case PrintDataEnum.WeldingSpotWidthValueLimit:
  8916. if (model != null)
  8917. value = $"上限:{model.WeldingSpotWidthBaseValue + model.WeldingSpotWidthUpFloatValue}\r\n下限:{model.WeldingSpotWidthBaseValue - model.WeldingSpotWidthDownFloatValue}";
  8918. else
  8919. value = "No Find";
  8920. break;
  8921. case PrintDataEnum.DefectCount:
  8922. value = order.DefectCount.ToString();
  8923. break;
  8924. case PrintDataEnum.DKCount:
  8925. value = order.DKCount.ToString();
  8926. break;
  8927. case PrintDataEnum.ZWCount:
  8928. value = order.ZWCount.ToString();
  8929. break;
  8930. case PrintDataEnum.GSYCCount:
  8931. value = order.GSYCCount.ToString();
  8932. break;
  8933. case PrintDataEnum.XWSCount:
  8934. value = order.XWSCount.ToString();
  8935. break;
  8936. case PrintDataEnum.QKCount:
  8937. value = order.QKCount.ToString();
  8938. break;
  8939. case PrintDataEnum.ZKCount:
  8940. value = order.ZKCount.ToString();
  8941. break;
  8942. case PrintDataEnum.PPCount:
  8943. value = order.PPCount.ToString();
  8944. break;
  8945. case PrintDataEnum.HSCount:
  8946. value = order.HSCount.ToString();
  8947. break;
  8948. case PrintDataEnum.YXCount:
  8949. value = order.YXCount.ToString();
  8950. break;
  8951. case PrintDataEnum.XBCount:
  8952. value = order.XBCount.ToString();
  8953. break;
  8954. case PrintDataEnum.SXCount:
  8955. value = order.SXCount.ToString();
  8956. break;
  8957. case PrintDataEnum.DSCount:
  8958. value = order.DSCount.ToString();
  8959. break;
  8960. case PrintDataEnum.GSDLCount:
  8961. value = order.GSDLCount.ToString();
  8962. break;
  8963. case PrintDataEnum.CJDKCount:
  8964. value = order.CJDKCount.ToString();
  8965. break;
  8966. }
  8967. break;
  8968. }
  8969. }
  8970. printData.Add(item.Key, value);
  8971. }
  8972. }
  8973. }
  8974. if ((ret)&& (printerType == PrinterType.Label))
  8975. {
  8976. if (data != null)
  8977. if (!printControl.BarTenderSetData(printData))
  8978. ret = false;
  8979. if (!printControl.BarTenderPrint(printerName))
  8980. ret = false;
  8981. }
  8982. else if ((ret) && (printerType == PrinterType.Excel))
  8983. {
  8984. //只是要sheet1
  8985. printControl.ExcelSelectSheet(1);
  8986. if (data != null)
  8987. if (!printControl.ExcelSetDataValue(printData))
  8988. ret = false;
  8989. if (!printControl.ExcelPrintData(printerName))
  8990. ret = false;
  8991. }
  8992. }
  8993. catch (Exception ex)
  8994. {
  8995. Log("标签打印", $"打印失败: {ex.Message}", WarningEnum.Low);
  8996. ret = false;
  8997. }
  8998. return ret;
  8999. }
  9000. public bool PrintFileData(PrinterType printerType, string printerName, string printerTemp, List<PrintInfo> data, Product model)
  9001. {
  9002. bool ret = true;
  9003. try
  9004. {
  9005. //Log("标签打印", $"打印机:{printerName}, 模板路径={printerTemp}");
  9006. if (printerType == PrinterType.Label)
  9007. {
  9008. if (!printControl.BarTenderOpenFile(printerTemp))
  9009. ret = false;
  9010. }
  9011. else if (printerType == PrinterType.Excel)
  9012. {
  9013. if (!printControl.ExcelOpenFile(printerTemp))
  9014. ret = false;
  9015. }
  9016. Dictionary<string, string> printData = new Dictionary<string, string>();
  9017. if (ret)
  9018. {
  9019. if (data != null)
  9020. {
  9021. foreach (var item in data)
  9022. {
  9023. string value = "";
  9024. //List<string> printCodes = new List<string>();
  9025. ////获取所有code代码
  9026. //foreach (var s in System.Enum.GetValues(typeof(PrintDataPdtEnum)))
  9027. //{
  9028. // PrintDataPdtEnum dataEnum = (PrintDataPdtEnum)s;
  9029. // printCodes.Add(dataEnum.GetDescription());
  9030. //}
  9031. //string[] defectCodes = new string[]
  9032. //{
  9033. // "ExcelDefectCount","ExcelDKCount","ExcelZWCount","ExcelGSYCCount","ExcelXWSCount","ExcelQKCount",
  9034. // "ExcelZKCount","ExcelPPCount","ExcelHSCount", "ExcelYXCount","ExcelXBCount","ExcelSXCount",
  9035. // "LabelDefectCount","LabelDKCount","LabelZWCount","LabelGSYCCount","LabelXWSCount","LabelQKCount",
  9036. // "LabelZKCount","LabelPPCount","LabelHSCount","LabelYXCount","LabelXBCount","LabelSXCount"
  9037. //};
  9038. //printCodes.AddRange(defectCodes);
  9039. //直接添加数据
  9040. if((printerType == PrinterType.Label)&& item.Type == 1 && item.IsValue) //标签数据
  9041. {
  9042. if (printData.ContainsKey(item.PrintKey))
  9043. printData.Remove(item.PrintKey);
  9044. printData.Add(item.PrintKey, item.PrintCode);
  9045. }
  9046. else if((printerType == PrinterType.Excel) && item.Type == 0 && item.IsValue) //excel数据
  9047. {
  9048. if (printData.ContainsKey(item.PrintKey))
  9049. printData.Remove(item.PrintKey);
  9050. printData.Add(item.PrintKey, item.PrintCode);
  9051. }
  9052. else if ((printerType == PrinterType.Label) && item.Type == 1 && !item.IsValue) //标签Code
  9053. {
  9054. switch (item.PrintCode)
  9055. {
  9056. case "料号批次":
  9057. value = order.BatchId;
  9058. break;
  9059. case "外观比对":
  9060. value = order.CompareResult == 0 ? "未比对" : order.CompareResult == 1 ? "OK" : "NG";
  9061. break;
  9062. case "检测结果":
  9063. value = order.Qualified ? "合格" : "不合格";
  9064. break;
  9065. case "料号":
  9066. value = order.OrderCode;
  9067. break;
  9068. case "料号名称":
  9069. if (model != null)
  9070. value = model.Name;
  9071. else
  9072. value = "No Find";
  9073. break;
  9074. case "网版编码":
  9075. value = order.SN;
  9076. break;
  9077. case "检测单号":
  9078. value = order.DetectOrder;
  9079. break;
  9080. case "检测时间":
  9081. value = order.CreateTime.ToString("yyyy/MM/dd HH:mm");
  9082. break;
  9083. case "操作员":
  9084. value = userMgr.LoginUser.Name;
  9085. break;
  9086. case "LabelDefectCount":
  9087. value = order.DefectCount.ToString();
  9088. break;
  9089. case "LabelDKCount":
  9090. value = order.DKCount.ToString();
  9091. break;
  9092. case "LabelZWCount":
  9093. value = order.ZWCount.ToString();
  9094. break;
  9095. case "LabelGSYCCount":
  9096. value = order.GSYCCount.ToString();
  9097. break;
  9098. case "LabelXWSCount":
  9099. value = order.XWSCount.ToString();
  9100. break;
  9101. case "LabelQKCount":
  9102. value = order.QKCount.ToString();
  9103. break;
  9104. case "LabelZKCount":
  9105. value = order.ZKCount.ToString();
  9106. break;
  9107. case "LabelPPCount":
  9108. value = order.PPCount.ToString();
  9109. break;
  9110. case "LabelHSCount":
  9111. value = order.HSCount.ToString();
  9112. break;
  9113. case "LabelYXCount":
  9114. value = order.YXCount.ToString();
  9115. break;
  9116. case "LabelXBCount":
  9117. value = order.XBCount.ToString();
  9118. break;
  9119. case "LabelSXCount":
  9120. value = order.SXCount.ToString();
  9121. break;
  9122. case "LabelDSCount":
  9123. value = order.DSCount.ToString();
  9124. break;
  9125. case "LabelGSDLCount":
  9126. value = order.GSDLCount.ToString();
  9127. break;
  9128. case "LabelCJDKCount":
  9129. value = order.CJDKCount.ToString();
  9130. break;
  9131. }
  9132. if (printData.ContainsKey(item.PrintKey))
  9133. printData.Remove(item.PrintKey);
  9134. printData.Add(item.PrintKey, item.PrintCode);
  9135. }
  9136. else if ((printerType == PrinterType.Excel) && item.Type == 0 && !item.IsValue) //excel Code
  9137. {
  9138. switch (item.PrintCode)
  9139. {
  9140. case "料号批次":
  9141. value = order.BatchId;
  9142. break;
  9143. case "外观比对":
  9144. value = order.CompareResult == 0 ? "未比对" : order.CompareResult == 1 ? "OK" : "NG";
  9145. break;
  9146. case "检测结果":
  9147. value = order.Qualified ? "合格" : "不合格";
  9148. break;
  9149. case "料号":
  9150. value = order.OrderCode;
  9151. break;
  9152. case "料号名称":
  9153. if (model != null)
  9154. value = model.Name;
  9155. else
  9156. value = "No Find";
  9157. break;
  9158. case "网版编码":
  9159. value = order.SN;
  9160. break;
  9161. case "检测单号":
  9162. value = order.DetectOrder;
  9163. break;
  9164. case "检测时间":
  9165. value = order.CreateTime.ToString("yyyy/MM/dd HH:mm");
  9166. break;
  9167. case "操作员":
  9168. value = userMgr.LoginUser.Name;
  9169. break;
  9170. #region 缺陷信息
  9171. case "ExcelDefectCount":
  9172. value = order.DefectCount.ToString();
  9173. break;
  9174. case "ExcelDKCount":
  9175. value = order.DKCount.ToString();
  9176. break;
  9177. case "ExcelZWCount":
  9178. value = order.ZWCount.ToString();
  9179. break;
  9180. case "ExcelGSYCCount":
  9181. value = order.GSYCCount.ToString();
  9182. break;
  9183. case "ExcelXWSCount":
  9184. value = order.XWSCount.ToString();
  9185. break;
  9186. case "ExcelQKCount":
  9187. value = order.QKCount.ToString();
  9188. break;
  9189. case "ExcelZKCount":
  9190. value = order.ZKCount.ToString();
  9191. break;
  9192. case "ExcelPPCount":
  9193. value = order.PPCount.ToString();
  9194. break;
  9195. case "ExcelHSCount":
  9196. value = order.HSCount.ToString();
  9197. break;
  9198. case "ExcelYXCount":
  9199. value = order.YXCount.ToString();
  9200. break;
  9201. case "ExcelXBCount":
  9202. value = order.XBCount.ToString();
  9203. break;
  9204. case "ExcelSXCount":
  9205. value = order.SXCount.ToString();
  9206. break;
  9207. case "ExcelDSCount":
  9208. value = order.DSCount.ToString();
  9209. break;
  9210. case "ExcelGSDLCount":
  9211. value = order.GSDLCount.ToString();
  9212. break;
  9213. case "ExcelCJDKCount":
  9214. value = order.CJDKCount.ToString();
  9215. break;
  9216. #endregion
  9217. }
  9218. if (printData.ContainsKey(item.PrintKey))
  9219. printData.Remove(item.PrintKey);
  9220. printData.Add(item.PrintKey, item.PrintCode);
  9221. }
  9222. }
  9223. }
  9224. }
  9225. if ((ret) && (printerType == PrinterType.Label))
  9226. {
  9227. if (data != null)
  9228. if (!printControl.BarTenderSetData(printData))
  9229. ret = false;
  9230. if (!printControl.BarTenderPrint(printerName))
  9231. ret = false;
  9232. }
  9233. else if ((ret) && (printerType == PrinterType.Excel))
  9234. {
  9235. //只是要sheet1
  9236. printControl.ExcelSelectSheet(1);
  9237. if (data != null)
  9238. if (!printControl.ExcelSetDataValue(printData))
  9239. ret = false;
  9240. if (!printControl.ExcelPrintData(printerName))
  9241. ret = false;
  9242. }
  9243. }
  9244. catch (Exception ex)
  9245. {
  9246. Log("标签打印", $"打印失败: {ex.Message}", WarningEnum.Low);
  9247. ret = false;
  9248. }
  9249. return ret;
  9250. }
  9251. public bool PrintFileOrderData(string printerName, string printerTemp, List<PrintInfo> data, Product model)
  9252. {
  9253. bool ret = true;
  9254. try
  9255. {
  9256. if (!printControl.ExcelOpenFile(printerTemp))
  9257. ret = false;
  9258. Dictionary<string, string> printData = new Dictionary<string, string>();
  9259. if (ret)
  9260. {
  9261. if (data != null)
  9262. {
  9263. foreach (var item in data)
  9264. {
  9265. string value = "";
  9266. //直接添加数据
  9267. if (item.Type == 3 && item.IsValue) //excel数据
  9268. {
  9269. if(!printData.ContainsKey(item.PrintKey))
  9270. printData.Add(item.PrintKey, item.PrintCode);
  9271. else
  9272. {
  9273. printData.Remove(item.PrintKey);
  9274. printData.Add(item.PrintKey, item.PrintCode);
  9275. }
  9276. }
  9277. else if ( item.Type == 3 && !item.IsValue) //excel Code
  9278. {
  9279. switch (item.PrintCode)
  9280. {
  9281. case "料号批次":
  9282. value = order.BatchId;
  9283. break;
  9284. case "外观比对":
  9285. if(CurrDefectOrders != null)
  9286. {
  9287. value = CurrDefectOrders.Exists(t => t.CompareResult == 2) ? "不通过" : "通过";
  9288. }
  9289. break;
  9290. case "检测结果":
  9291. if (CurrDefectOrders != null)
  9292. {
  9293. value = CurrDefectOrders.Exists(t => t.Qualified == false) ? "不合格" : "合格";
  9294. }
  9295. //value = order.Qualified ? "合格" : "不合格";
  9296. break;
  9297. case "检测数量":
  9298. value = TotalCnt.ToString();
  9299. break;
  9300. case "合格数量":
  9301. if (CurrDefectOrders != null)
  9302. {
  9303. value = CurrDefectOrders.FindAll(t => t.Qualified == true).Count.ToString();
  9304. }
  9305. break;
  9306. case "不合格数量":
  9307. if (CurrDefectOrders != null)
  9308. {
  9309. value = CurrDefectOrders.FindAll(t => t.Qualified == false).Count.ToString();
  9310. }
  9311. break;
  9312. case "料号":
  9313. value = order.OrderCode;
  9314. break;
  9315. case "料号名称":
  9316. if (model != null)
  9317. value = model.Name;
  9318. else
  9319. value = "No Find";
  9320. break;
  9321. case "网版编码":
  9322. value = order.SN;
  9323. break;
  9324. case "检测单号":
  9325. value = order.DetectOrder;
  9326. break;
  9327. case "检测时间":
  9328. value = order.CreateTime.ToString("yyyy/MM/dd HH:mm");
  9329. break;
  9330. case "检测日期":
  9331. value = order.CreateTime.ToString("yyyy/MM/dd");
  9332. break;
  9333. case "操作员":
  9334. value = userMgr.LoginUser.Name;
  9335. break;
  9336. case "综合":
  9337. if (CurrDefectOrders != null)
  9338. {
  9339. List<SizeDefectInfo> frt = new List<SizeDefectInfo>();
  9340. for (int i = 0; i < CurrDefectOrders.Count; i++)
  9341. {
  9342. //获取当前步骤的均值结果
  9343. var tyy = CurrDefectOrders[i].SizeDefectInfoList.FindAll(t => (t.StepName == item.PrintName && t.isAverage == true));
  9344. if (tyy != null && tyy.Count > 0)
  9345. frt.AddRange(tyy);
  9346. }
  9347. value = frt.Exists(t => t.result == 2) ? "不合格" : "合格";
  9348. }
  9349. break;
  9350. #region 缺陷信息
  9351. case "ExcelDefectCount":
  9352. value = order.DefectCount.ToString();
  9353. break;
  9354. case "ExcelDKCount":
  9355. value = order.DKCount.ToString();
  9356. break;
  9357. case "ExcelZWCount":
  9358. value = order.ZWCount.ToString();
  9359. break;
  9360. case "ExcelGSYCCount":
  9361. value = order.GSYCCount.ToString();
  9362. break;
  9363. case "ExcelXWSCount":
  9364. value = order.XWSCount.ToString();
  9365. break;
  9366. case "ExcelQKCount":
  9367. value = order.QKCount.ToString();
  9368. break;
  9369. case "ExcelZKCount":
  9370. value = order.ZKCount.ToString();
  9371. break;
  9372. case "ExcelPPCount":
  9373. value = order.PPCount.ToString();
  9374. break;
  9375. case "ExcelHSCount":
  9376. value = order.HSCount.ToString();
  9377. break;
  9378. case "ExcelYXCount":
  9379. value = order.YXCount.ToString();
  9380. break;
  9381. case "ExcelXBCount":
  9382. value = order.XBCount.ToString();
  9383. break;
  9384. case "ExcelSXCount":
  9385. value = order.SXCount.ToString();
  9386. break;
  9387. case "ExcelDSCount":
  9388. value = order.DSCount.ToString();
  9389. break;
  9390. case "ExcelGSDLCount":
  9391. value = order.GSDLCount.ToString();
  9392. break;
  9393. case "ExcelCJDKCount":
  9394. value = order.CJDKCount.ToString();
  9395. break;
  9396. #endregion
  9397. }
  9398. if (!printData.ContainsKey(item.PrintKey))
  9399. printData.Add(item.PrintKey, value);
  9400. }
  9401. }
  9402. }
  9403. }
  9404. //只是要sheet1
  9405. printControl.ExcelSelectSheet(1);
  9406. if (data != null)
  9407. if (!printControl.ExcelSetDataValue(printData))
  9408. ret = false;
  9409. if (!printControl.ExcelPrintData(printerName))
  9410. ret = false;
  9411. }
  9412. catch (Exception ex)
  9413. {
  9414. Log("标签打印", $"打印失败: {ex.Message}", WarningEnum.Low);
  9415. ret = false;
  9416. }
  9417. return ret;
  9418. }
  9419. #endregion
  9420. #region 获取Mes上传数据
  9421. private string GetMesString(string mesJsonTemp, Product model, bool isNewStep)
  9422. {
  9423. string jsonData = "";
  9424. string txt = "";
  9425. try
  9426. {
  9427. var fileDir = mesJsonTemp;
  9428. byte[] allBytes = null;
  9429. byte[] buffer = new byte[1024];//一个1K的缓冲字节容器
  9430. Stopwatch stopwatch = new Stopwatch();
  9431. stopwatch.Restart();
  9432. using (MemoryStream ms = new MemoryStream())
  9433. {
  9434. using (FileStream fs = new FileStream(fileDir, FileMode.Open, FileAccess.Read))
  9435. {
  9436. int positon = 0;
  9437. while ((positon = fs.Read(buffer, 0, buffer.Length)) > 0)
  9438. {
  9439. ms.Write(buffer, 0, positon);
  9440. }
  9441. allBytes = ms.ToArray();
  9442. }
  9443. }
  9444. stopwatch.Stop();
  9445. if (null != allBytes)
  9446. {
  9447. //尝试将字节转成字符串
  9448. txt = System.Text.Encoding.UTF8.GetString(allBytes);
  9449. // this.richTextBox_Result.Text = txt;
  9450. }
  9451. //string[] txtToArray = txt.Split('\r');
  9452. //解析格式
  9453. if (!string.IsNullOrEmpty(txt))
  9454. {
  9455. Type t = typeof(MesCodeEnum);
  9456. FieldInfo[] fieldInfos = t.GetFields();
  9457. foreach (var item in fieldInfos)
  9458. {
  9459. if (item.FieldType.IsEnum)
  9460. {
  9461. switch ((MesCodeEnum)t.InvokeMember(item.Name, BindingFlags.GetField, null, null, null))
  9462. {
  9463. case MesCodeEnum.MM0001:
  9464. txt = txt.Replace(item.Name, order.DetectOrder);
  9465. break;
  9466. case MesCodeEnum.MM0002:
  9467. txt = txt.Replace(item.Name, order.OrderCode);
  9468. break;
  9469. case MesCodeEnum.MM0003:
  9470. txt = txt.Replace(item.Name, model.Name);
  9471. break;
  9472. case MesCodeEnum.MM0004:
  9473. txt = txt.Replace(item.Name, order.SN);
  9474. break;
  9475. case MesCodeEnum.MM0005:
  9476. txt = txt.Replace(item.Name, userMgr.LoginUser.Name);
  9477. break;
  9478. case MesCodeEnum.MM0006:
  9479. txt = txt.Replace(item.Name, order.CreateTime.ToString("yyyy/MM/dd HH:mm"));
  9480. break;
  9481. case MesCodeEnum.MM0007:
  9482. txt = txt.Replace(item.Name, order.BatchId);
  9483. break;
  9484. case MesCodeEnum.MM0008:
  9485. txt = txt.Replace(item.Name, order.CompareResult == 0 ? "未比对" : order.CompareResult == 1 ? "OK" : "NG");
  9486. break;
  9487. case MesCodeEnum.MM0009:
  9488. txt = txt.Replace(item.Name, order.Qualified ? "合格" : "不合格");
  9489. break;
  9490. case MesCodeEnum.MM0010:
  9491. txt = txt.Replace(item.Name, order.TensionValue.ToString("0.000"));
  9492. break;
  9493. case MesCodeEnum.MM0011:
  9494. txt = txt.Replace(item.Name, order.HeightValue.ToString("0.000"));
  9495. break;
  9496. case MesCodeEnum.MM0012:
  9497. txt = txt.Replace(item.Name, order.LineWidthValue.ToString("0.000"));
  9498. break;
  9499. case MesCodeEnum.MM0013:
  9500. txt = txt.Replace(item.Name, order.PTValue.ToString("0.0000"));
  9501. break;
  9502. case MesCodeEnum.MM0014:
  9503. txt = txt.Replace(item.Name, order.XPTValue.ToString("0.0000"));
  9504. break;
  9505. case MesCodeEnum.MALL000:
  9506. txt = txt.Replace(item.Name, order.DefectCount.ToString());
  9507. break;
  9508. case MesCodeEnum.MDK000:
  9509. txt = txt.Replace(item.Name, order.DKCount.ToString());
  9510. break;
  9511. case MesCodeEnum.MZW000:
  9512. txt = txt.Replace(item.Name, order.ZWCount.ToString());
  9513. break;
  9514. case MesCodeEnum.MGSYC000:
  9515. txt = txt.Replace(item.Name, order.GSYCCount.ToString());
  9516. break;
  9517. case MesCodeEnum.MQWS000:
  9518. txt = txt.Replace(item.Name, order.XWSCount.ToString());
  9519. break;
  9520. case MesCodeEnum.MQK000:
  9521. txt = txt.Replace(item.Name, order.QKCount.ToString());
  9522. break;
  9523. case MesCodeEnum.MZK000:
  9524. txt = txt.Replace(item.Name, order.ZKCount.ToString());
  9525. break;
  9526. case MesCodeEnum.MPP000:
  9527. txt = txt.Replace(item.Name, order.PPCount.ToString());
  9528. break;
  9529. case MesCodeEnum.MHS000:
  9530. txt = txt.Replace(item.Name, order.HSCount.ToString());
  9531. break;
  9532. case MesCodeEnum.MYX000:
  9533. txt = txt.Replace(item.Name, order.YXCount.ToString());
  9534. break;
  9535. case MesCodeEnum.MXB000:
  9536. txt = txt.Replace(item.Name, order.XBCount.ToString());
  9537. break;
  9538. case MesCodeEnum.MSX000:
  9539. txt = txt.Replace(item.Name, order.SXCount.ToString());
  9540. break;
  9541. }
  9542. }
  9543. }
  9544. }
  9545. //单点数据
  9546. if (!string.IsNullOrEmpty(txt))
  9547. {
  9548. if (!isNewStep)
  9549. {
  9550. txt = txt.Replace("MTV001", order.Tension1.ToString("0.000"));
  9551. txt = txt.Replace("MTV002", order.Tension2.ToString("0.000"));
  9552. txt = txt.Replace("MTV003", order.Tension3.ToString("0.000"));
  9553. txt = txt.Replace("MTV004", order.Tension4.ToString("0.000"));
  9554. txt = txt.Replace("MTV005", order.Tension5.ToString("0.000"));
  9555. txt = txt.Replace("MHV001", order.Height1.ToString("0.000"));
  9556. txt = txt.Replace("MHV002", order.Height2.ToString("0.000"));
  9557. txt = txt.Replace("MHV003", order.Height3.ToString("0.000"));
  9558. txt = txt.Replace("MHV004", order.Height4.ToString("0.000"));
  9559. txt = txt.Replace("MHV005", order.Height5.ToString("0.000"));
  9560. txt = txt.Replace("MYPTV001", order.PT1.ToString("0.0000"));
  9561. txt = txt.Replace("MYPTV002", order.PT2.ToString("0.0000"));
  9562. txt = txt.Replace("MYPTV003", order.PT3.ToString("0.0000"));
  9563. txt = txt.Replace("MYPTV004", order.PT5.ToString("0.0000"));
  9564. txt = txt.Replace("MYPTV005", order.PT6.ToString("0.0000"));
  9565. txt = txt.Replace("MLWV001", order.LineWidth1.ToString("0.000"));
  9566. txt = txt.Replace("MLWV002", order.LineWidth2.ToString("0.000"));
  9567. txt = txt.Replace("MLWV003", order.LineWidth3.ToString("0.000"));
  9568. txt = txt.Replace("MLWV004", order.LineWidth4.ToString("0.000"));
  9569. txt = txt.Replace("MLWV005", order.LineWidth5.ToString("0.000"));
  9570. txt = txt.Replace("MLWV006", order.LineWidth6.ToString("0.000"));
  9571. txt = txt.Replace("MLWV007", order.LineWidth7.ToString("0.000"));
  9572. txt = txt.Replace("MLWV008", order.LineWidth8.ToString("0.000"));
  9573. txt = txt.Replace("MLWV009", order.LineWidth9.ToString("0.000"));
  9574. }
  9575. else
  9576. {
  9577. string[] pointType = new string[11] {"Tension", "Height", "Y轴方向PT值检测" , "线宽正面" , "反面检测" ,
  9578. "X轴方向PT值检测","主栅连接线检测","主栅宽度检测","主栅间距","细栅间距检测","背极宽度"};
  9579. string[] codeType = new string[11] {"MTV00", "MHV00", "MYPTV00" , "MLWV00" , "MLWV00" ,
  9580. "MXPTV00","MTV00","MTV00","MTV00","MTV00","MTV00"};
  9581. for (int i = 0; i < pointType.Length; i++)
  9582. {
  9583. List<SizeDefectInfo> t1 = order.SizeDefectInfoList.Where(q => q.PointCode == pointType[i]).ToList();
  9584. for (int j = 0; j < t1.Count; j++)
  9585. {
  9586. txt = txt.Replace(codeType[i] + (i + 1).ToString(), t1[j].Data.ToString("0.0000"));
  9587. }
  9588. }
  9589. }
  9590. }
  9591. }
  9592. catch (Exception ex) {
  9593. Log("MES数据解析", "解析错误:" + ex.Message, WarningEnum.High);
  9594. }
  9595. jsonData = txt;
  9596. return jsonData;
  9597. }
  9598. #endregion
  9599. #region 缺陷分布
  9600. public bool GetDefectDistribution(out string imagePath, out Order outOrder)
  9601. {
  9602. bool ret = false;
  9603. imagePath = "";
  9604. outOrder = null;
  9605. if (CurrProductModel == null || order == null || order.DefectInfoList == null || order.DefectInfoList.Count < 1)
  9606. {
  9607. Log("缺陷分布", "无数据", WarningEnum.Low);
  9608. return false;
  9609. }
  9610. //图纸
  9611. try
  9612. {
  9613. string gbxBmpPath = "";
  9614. var attachmentFile = CurrProductModel.AttachmentList.FirstOrDefault(x => x.Type == 0);
  9615. if (attachmentFile != null)
  9616. {
  9617. gbxBmpPath = confMgr.ProjectDir + $"\\{attachmentFile.NameTimestamp}";
  9618. if (!File.Exists(gbxBmpPath + ".bmp"))
  9619. gbxBmpPath = "";
  9620. }
  9621. if (string.IsNullOrEmpty(gbxBmpPath))
  9622. {
  9623. Log("缺陷分布", "图纸文件不存在!", WarningEnum.Low);
  9624. MessageBox.Show("图纸文件不存在!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  9625. return false;
  9626. }
  9627. if (!File.Exists(gbxBmpPath + ".jpg"))//转背景后的图纸文件
  9628. {
  9629. //换背景JPG
  9630. Mat mat = Cv2.ImRead(gbxBmpPath + ".bmp");
  9631. Cv2.CvtColor(mat, mat, ColorConversionCodes.RGB2GRAY);//转灰度图
  9632. for (int i = 0; i < mat.Height; i++)
  9633. {
  9634. for (int j = 0; j < mat.Width; j++)
  9635. {
  9636. if (mat.At<byte>(i, j) == 255)//白色
  9637. mat.Set<byte>(i, j, 0);
  9638. else
  9639. mat.Set<byte>(i, j, 255);
  9640. }
  9641. }
  9642. OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat).Save(gbxBmpPath + ".jpg", ImageFormat.Jpeg);
  9643. }
  9644. imagePath = gbxBmpPath + ".jpg";
  9645. outOrder = order;
  9646. return true;
  9647. }
  9648. catch (Exception ex)
  9649. {
  9650. MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0);
  9651. }
  9652. return ret;
  9653. }
  9654. #endregion
  9655. #region 尺寸缺陷禁用
  9656. public void SetSizeEnable(bool val)
  9657. {
  9658. SizeEnable = val;
  9659. Log("尺寸检测", val?"尺寸启用":"尺寸禁用");
  9660. }
  9661. public void SetDefectEnable(bool val)
  9662. {
  9663. DefectEnable = val;
  9664. Log("缺陷检测", val ? "缺陷启用" : "缺陷禁用");
  9665. }
  9666. #endregion
  9667. #region 打印队列
  9668. private void PrintDataList(string processName, TensionProp TensionParam, double baseValue, double upLimit, double loLimit)
  9669. {
  9670. try
  9671. {
  9672. if (TensionParam.OpenPrint)
  9673. {
  9674. if (!string.IsNullOrEmpty(TensionParam.ExcelData))
  9675. CurrPrintInfos.Add(new PrintInfo()
  9676. {
  9677. Type = 0,
  9678. IsValue = true,
  9679. PrintKey = TensionParam.ExcelData,
  9680. PrintCode = order.TensionValue.ToString("0.00"),
  9681. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9682. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9683. });
  9684. if (!string.IsNullOrEmpty(TensionParam.ExcelLimit))
  9685. CurrPrintInfos.Add(new PrintInfo()
  9686. {
  9687. Type = 0,
  9688. IsValue = true,
  9689. PrintKey = TensionParam.ExcelLimit,
  9690. PrintCode = ((TensionParam.OpenUseLimit)&&(TensionParam.MaxLimit + TensionParam.MinLimit>0)&&
  9691. (TensionParam.MaxLimit == TensionParam .MinLimit))? $"{TensionParam.StandardValues}±{TensionParam.MaxLimit}":
  9692. $"上限:{baseValue+ upLimit}\r\n下限:{baseValue-loLimit}",
  9693. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9694. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9695. });
  9696. }
  9697. if (TensionParam.OpenPrintLabel)
  9698. {
  9699. if (!string.IsNullOrEmpty(TensionParam.ExcelData))
  9700. CurrPrintInfos.Add(new PrintInfo()
  9701. {
  9702. Type = 1,
  9703. IsValue = true,
  9704. PrintKey = TensionParam.ExcelData,
  9705. PrintCode = order.TensionValue.ToString("0.00"),
  9706. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9707. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9708. });
  9709. if (!string.IsNullOrEmpty(TensionParam.ExcelLimit))
  9710. CurrPrintInfos.Add(new PrintInfo()
  9711. {
  9712. Type = 1,
  9713. IsValue = true,
  9714. PrintKey = TensionParam.ExcelLimit,
  9715. PrintCode = ((TensionParam.OpenUseLimit) && (TensionParam.MaxLimit + TensionParam.MinLimit > 0) &&
  9716. (TensionParam.MaxLimit == TensionParam.MinLimit)) ? $"{TensionParam.StandardValues}±{TensionParam.MaxLimit}" :
  9717. $"上限:{baseValue + upLimit}\r\n下限:{baseValue - loLimit}",
  9718. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9719. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9720. });
  9721. }
  9722. if (TensionParam.OpenPrintOrder)
  9723. {
  9724. if (!string.IsNullOrEmpty(TensionParam.OrderData))
  9725. if (CurrDefectIndex < TensionParam.OrderData.Split(',').Length)
  9726. {
  9727. CurrOrderPrintInfos.Add(new PrintInfo()
  9728. {
  9729. Type = 3,
  9730. IsValue = true,
  9731. PrintKey = TensionParam.OrderData.Split(',')[CurrDefectIndex],
  9732. PrintCode = order.TensionValue.ToString("0.00"),
  9733. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9734. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9735. });
  9736. }
  9737. if (!string.IsNullOrEmpty(TensionParam.OrderLimit))
  9738. CurrOrderPrintInfos.Add(new PrintInfo()
  9739. {
  9740. Type = 3,
  9741. IsValue = true,
  9742. PrintKey = TensionParam.OrderLimit,
  9743. PrintCode = ((TensionParam.OpenUseLimit) && (TensionParam.MaxLimit + TensionParam.MinLimit > 0) &&
  9744. (TensionParam.MaxLimit == TensionParam.MinLimit)) ? $"{TensionParam.StandardValues}±{TensionParam.MaxLimit}" :
  9745. $"上限:{baseValue + upLimit}\r\n下限:{baseValue - loLimit}",
  9746. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9747. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9748. });
  9749. if (!string.IsNullOrEmpty(TensionParam.OrderTestName))
  9750. CurrOrderPrintInfos.Add(new PrintInfo()
  9751. {
  9752. Type = 3,
  9753. IsValue = true,
  9754. PrintKey = TensionParam.OrderTestName,
  9755. PrintCode = processName,
  9756. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9757. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9758. });
  9759. if (!string.IsNullOrEmpty(TensionParam.OrderTestResult))
  9760. CurrOrderPrintInfos.Add(new PrintInfo()
  9761. {
  9762. Type = 3,
  9763. IsValue = false,
  9764. PrintKey = TensionParam.OrderTestResult,
  9765. PrintCode = "综合",
  9766. PrintName = processName,
  9767. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9768. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9769. });
  9770. }
  9771. }
  9772. catch (Exception ex)
  9773. {
  9774. throw new Exception($"打印参数错误:{ex.Message}");
  9775. }
  9776. }
  9777. private void PrintDataList(string processName, ThicknessProp ThicknessParam, double baseValue, double upLimit, double loLimit)
  9778. {
  9779. try
  9780. {
  9781. if (ThicknessParam.OpenPrint)
  9782. {
  9783. if (!string.IsNullOrEmpty(ThicknessParam.ExcelData))
  9784. CurrPrintInfos.Add(new PrintInfo()
  9785. {
  9786. Type = 0,
  9787. IsValue = true,
  9788. PrintKey = ThicknessParam.ExcelData,
  9789. PrintCode = order.HeightValue.ToString("0.00"),
  9790. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9791. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9792. });
  9793. if (!string.IsNullOrEmpty(ThicknessParam.ExcelLimit))
  9794. CurrPrintInfos.Add(new PrintInfo()
  9795. {
  9796. Type = 0,
  9797. IsValue = true,
  9798. PrintKey = ThicknessParam.ExcelLimit,
  9799. PrintCode = ((ThicknessParam.OpenUseLimit) && (ThicknessParam.MaxLimit + ThicknessParam.MinLimit > 0) &&
  9800. (ThicknessParam.MaxLimit == ThicknessParam.MinLimit)) ? $"{ThicknessParam.StandardValues}±{ThicknessParam.MaxLimit}" :
  9801. $"上限:{baseValue + upLimit}\r\n下限:{baseValue - loLimit}",
  9802. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9803. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9804. });
  9805. }
  9806. if (ThicknessParam.OpenPrintLabel)
  9807. {
  9808. if (!string.IsNullOrEmpty(ThicknessParam.ExcelData))
  9809. CurrPrintInfos.Add(new PrintInfo()
  9810. {
  9811. Type = 1,
  9812. IsValue = true,
  9813. PrintKey = ThicknessParam.ExcelData,
  9814. PrintCode = order.HeightValue.ToString("0.00"),
  9815. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9816. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9817. });
  9818. if (!string.IsNullOrEmpty(ThicknessParam.ExcelLimit))
  9819. CurrPrintInfos.Add(new PrintInfo()
  9820. {
  9821. Type = 1,
  9822. IsValue = true,
  9823. PrintKey = ThicknessParam.ExcelLimit,
  9824. PrintCode = ((ThicknessParam.OpenUseLimit) && (ThicknessParam.MaxLimit + ThicknessParam.MinLimit > 0) &&
  9825. (ThicknessParam.MaxLimit == ThicknessParam.MinLimit)) ? $"{ThicknessParam.StandardValues}±{ThicknessParam.MaxLimit}" :
  9826. $"上限:{baseValue + upLimit}\r\n下限:{baseValue - loLimit}",
  9827. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9828. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9829. });
  9830. }
  9831. if (ThicknessParam.OpenPrintOrder)
  9832. {
  9833. if (!string.IsNullOrEmpty(ThicknessParam.OrderData))
  9834. if (CurrDefectIndex < ThicknessParam.OrderData.Split(',').Length)
  9835. CurrOrderPrintInfos.Add(new PrintInfo()
  9836. {
  9837. Type = 3,
  9838. IsValue = true,
  9839. PrintKey = ThicknessParam.OrderData.Split(',')[CurrDefectIndex],
  9840. PrintCode = order.HeightValue.ToString("0.00"),
  9841. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9842. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9843. });
  9844. if (!string.IsNullOrEmpty(ThicknessParam.OrderLimit))
  9845. CurrOrderPrintInfos.Add(new PrintInfo()
  9846. {
  9847. Type = 3,
  9848. IsValue = true,
  9849. PrintKey = ThicknessParam.OrderLimit,
  9850. PrintCode = ((ThicknessParam.OpenUseLimit) && (ThicknessParam.MaxLimit + ThicknessParam.MinLimit > 0) &&
  9851. (ThicknessParam.MaxLimit == ThicknessParam.MinLimit)) ? $"{ThicknessParam.StandardValues}±{ThicknessParam.MaxLimit}" :
  9852. $"上限:{baseValue + upLimit}\r\n下限:{baseValue - loLimit}",
  9853. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9854. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9855. });
  9856. if (!string.IsNullOrEmpty(ThicknessParam.OrderTestName))
  9857. CurrOrderPrintInfos.Add(new PrintInfo()
  9858. {
  9859. Type = 3,
  9860. IsValue = true,
  9861. PrintKey = ThicknessParam.OrderTestName,
  9862. PrintCode = processName,
  9863. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9864. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9865. });
  9866. if (!string.IsNullOrEmpty(ThicknessParam.OrderTestResult))
  9867. CurrOrderPrintInfos.Add(new PrintInfo()
  9868. {
  9869. Type = 3,
  9870. IsValue = false,
  9871. PrintKey = ThicknessParam.OrderTestResult,
  9872. PrintCode = "综合",
  9873. PrintName = processName,
  9874. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9875. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9876. });
  9877. }
  9878. }
  9879. catch (Exception ex)
  9880. {
  9881. throw new Exception($"打印参数错误:{ex.Message}");
  9882. }
  9883. }
  9884. private void PrintDataList(string processName, PointTestProp testParam, double data, double upLimit, double loLimit)
  9885. {
  9886. try
  9887. {
  9888. if (testParam.OpenPrint)
  9889. {
  9890. if (!string.IsNullOrEmpty(testParam.ExcelData))
  9891. CurrPrintInfos.Add(new PrintInfo()
  9892. {
  9893. Type = 0,
  9894. IsValue = true,
  9895. PrintKey = testParam.ExcelData,
  9896. PrintCode = data.ToString("0.0000"),
  9897. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9898. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9899. });
  9900. if (!string.IsNullOrEmpty(testParam.ExcelLimit))
  9901. CurrPrintInfos.Add(new PrintInfo()
  9902. {
  9903. Type = 0,
  9904. IsValue = true,
  9905. PrintKey = testParam.ExcelLimit,
  9906. PrintCode = ((testParam.MaxLimit + testParam.MinLimit)>0&&(testParam.MaxLimit == testParam.MinLimit)) ?
  9907. $"{testParam.StandardValues}±{testParam.MaxLimit}" : $"上限:{upLimit}\r\n下限:{loLimit}",
  9908. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9909. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9910. });
  9911. }
  9912. if (testParam.OpenPrintLabel)
  9913. {
  9914. if (!string.IsNullOrEmpty(testParam.ExcelData))
  9915. CurrPrintInfos.Add(new PrintInfo()
  9916. {
  9917. Type = 1,
  9918. IsValue = true,
  9919. PrintKey = testParam.ExcelData,
  9920. PrintCode = data.ToString("0.0000"),
  9921. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9922. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9923. });
  9924. if (!string.IsNullOrEmpty(testParam.ExcelLimit))
  9925. CurrPrintInfos.Add(new PrintInfo()
  9926. {
  9927. Type = 1,
  9928. IsValue = true,
  9929. PrintKey = testParam.ExcelLimit,
  9930. PrintCode = ((testParam.MaxLimit + testParam.MinLimit) > 0 && (testParam.MaxLimit == testParam.MinLimit)) ?
  9931. $"{testParam.StandardValues}±{testParam.MaxLimit}" : $"上限:{upLimit}\r\n下限:{loLimit}",
  9932. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9933. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9934. });
  9935. }
  9936. if (testParam.OpenPrintOrder)
  9937. {
  9938. if (!string.IsNullOrEmpty(testParam.OrderData))
  9939. if (CurrDefectIndex < testParam.OrderData.Split(',').Length)
  9940. CurrOrderPrintInfos.Add(new PrintInfo()
  9941. {
  9942. Type = 3,
  9943. IsValue = true,
  9944. PrintKey = testParam.OrderData.Split(',')[CurrDefectIndex],
  9945. PrintCode = data.ToString("0.0000"),
  9946. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9947. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9948. });
  9949. if (!string.IsNullOrEmpty(testParam.OrderLimit))
  9950. CurrOrderPrintInfos.Add(new PrintInfo()
  9951. {
  9952. Type = 3,
  9953. IsValue = true,
  9954. PrintKey = testParam.OrderLimit,
  9955. PrintCode = ((testParam.MaxLimit + testParam.MinLimit) > 0 && (testParam.MaxLimit == testParam.MinLimit)) ?
  9956. $"{testParam.StandardValues}±{testParam.MaxLimit}" : $"上限:{upLimit}\r\n下限:{loLimit}",
  9957. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9958. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9959. });
  9960. if (!string.IsNullOrEmpty(testParam.OrderTestName))
  9961. CurrOrderPrintInfos.Add(new PrintInfo()
  9962. {
  9963. Type = 3,
  9964. IsValue = true,
  9965. PrintKey = testParam.OrderTestName,
  9966. PrintCode = processName,
  9967. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9968. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9969. });
  9970. if (!string.IsNullOrEmpty(testParam.OrderTestResult))
  9971. CurrOrderPrintInfos.Add(new PrintInfo()
  9972. {
  9973. Type = 3,
  9974. IsValue = false,
  9975. PrintKey = testParam.OrderTestResult,
  9976. PrintCode = "综合",
  9977. PrintName = processName,
  9978. CreateUserCode = SysMgr.Instance.UserMgr.LoginUser.Code,
  9979. ModifyUserCode = SysMgr.Instance.UserMgr.LoginUser.Code
  9980. });
  9981. }
  9982. }
  9983. catch (Exception ex)
  9984. {
  9985. throw new Exception($"打印参数错误:{ex.Message}");
  9986. }
  9987. }
  9988. #endregion
  9989. }
  9990. #region 系统事件
  9991. /// <summary>
  9992. /// 流程事件
  9993. /// </summary>
  9994. public class RunEventArgs : EventArgs
  9995. {
  9996. private int _cmd;
  9997. public int Cmd { get { return _cmd; } }
  9998. private string _sn;
  9999. public string SN { get { return _sn; } }
  10000. private List<StepProcess> _stepProcesses;
  10001. public List<StepProcess> StepProcessesList { get { return _stepProcesses; } }
  10002. private bool _newStep;
  10003. public bool NewStep { get { return _newStep; } }
  10004. private int _stepIndex;
  10005. public int StepIndex { get { return _stepIndex; } }
  10006. private string _mesg;
  10007. public string Mesg { get { return _mesg; } }
  10008. private bool _compareResult;
  10009. public bool CompareResult { get { return _compareResult; } }
  10010. private string _compareResultString;
  10011. public string CompareResultString { get { return _compareResultString; } }
  10012. private long _time;
  10013. public long Time { get { return _time; } }
  10014. private int _num;
  10015. public long Num { get { return _num; } }
  10016. private long _cnt;
  10017. public long Cnt { get { return _cnt; } }
  10018. public RunEventArgs(string sn, List<StepProcess> list, bool newstep = false)
  10019. {
  10020. this._cmd = 0;
  10021. this._sn = sn;
  10022. this._stepProcesses = list;
  10023. this._newStep = newstep;
  10024. }
  10025. public RunEventArgs(int stepIndex)
  10026. {
  10027. this._cmd = 1;
  10028. this._stepIndex = stepIndex;
  10029. }
  10030. public RunEventArgs(int stepIndex, string mesg)
  10031. {
  10032. this._cmd = 2;
  10033. this._stepIndex = stepIndex;
  10034. _mesg = mesg;
  10035. }
  10036. public RunEventArgs(int cmd, bool rel, int cnt)
  10037. {
  10038. this._cmd = cmd;
  10039. this._compareResult = rel;
  10040. this._cnt = cnt;
  10041. }
  10042. public RunEventArgs(int cmd, bool rel, int cnt, string rel_str)
  10043. {
  10044. this._cmd = cmd;
  10045. this._compareResult = rel;
  10046. this._cnt = cnt;
  10047. this._compareResultString = rel_str;
  10048. }
  10049. public RunEventArgs(long time )
  10050. {
  10051. this._cmd = 7;
  10052. this._time = time;
  10053. }
  10054. public RunEventArgs(long time, int num)
  10055. {
  10056. this._cmd = 8;
  10057. this._time = time;
  10058. this._num = num;
  10059. }
  10060. private int _picIndex;
  10061. public int PicIndex { get { return _picIndex; } }
  10062. private HObject _pic;
  10063. public HObject Pic { get { return _pic; } }
  10064. public RunEventArgs(int index, HObject pic)
  10065. {
  10066. this._cmd = 6;
  10067. this._picIndex = index;
  10068. this._pic = pic.Clone();
  10069. }
  10070. private bool _over;
  10071. public bool Over { get { return _over; } }
  10072. public RunEventArgs(bool ov)
  10073. {
  10074. this._cmd = 10;
  10075. this._over = ov;
  10076. }
  10077. //测厚显示
  10078. private List<double> _value;
  10079. public List<double> Value { get { return _value; } }
  10080. private double _value_up;
  10081. public double Value_up { get { return _value_up; } }
  10082. private double _value_low;
  10083. public double Value_low { get { return _value_low; } }
  10084. public RunEventArgs(int cmd, List<double> val, double up, double low)
  10085. {
  10086. this._cmd = cmd;
  10087. this._value = val;
  10088. this._value_up = up;
  10089. this._value_low = low;
  10090. }
  10091. //新流程数据显示
  10092. private double _value_ave;
  10093. public double Value_ave { get { return _value_ave; } }
  10094. private int _processSts;
  10095. public int ProcessSts { get { return _processSts; } }
  10096. private bool _processType;
  10097. public bool ProcessType { get { return _processType; } }
  10098. public RunEventArgs(int stepIndex, string mesg, List<double> val, double rel_val, double max, double min, int proRel, bool type)
  10099. {
  10100. this._cmd = 30;
  10101. this._stepIndex = stepIndex;
  10102. this._mesg = mesg;
  10103. this._value = val;
  10104. this._value_ave = rel_val;
  10105. this._value_up = max;
  10106. this._value_low = min;
  10107. this._processSts = proRel;
  10108. this._processType = type;
  10109. }
  10110. public RunEventArgs(int stepIndex, string mesg, int proRel, bool type)
  10111. {
  10112. this._cmd = 31;
  10113. this._stepIndex = stepIndex;
  10114. this._mesg = mesg;
  10115. this._processSts = proRel;
  10116. this._processType = type;
  10117. }
  10118. }
  10119. /// <summary>
  10120. /// 显图事件
  10121. /// </summary>
  10122. public class ImgEventArgs : EventArgs
  10123. {
  10124. private Bitmap[] _bmps;
  10125. public Bitmap[] Bitmaps { get { return _bmps; } }
  10126. private Mat[] _bmps_cut;
  10127. public Mat[] Bmps_cut { get { return _bmps_cut; } }
  10128. private double _x;
  10129. public double X { get { return _x; } }
  10130. private double _y;
  10131. public double Y { get { return _y; } }
  10132. private List<Dictionary<int, List<string>[]>> _info;
  10133. public List<Dictionary<int, List<string>[]>> Info
  10134. {
  10135. get { return _info; }
  10136. }
  10137. public ImgEventArgs(Bitmap[] bmps, Mat[] bmps_cut, double Xmm, double Ymm, List<Dictionary<int, List<string>[]>> info)
  10138. {
  10139. this._bmps = new Bitmap[bmps.Length];
  10140. for (int i = 0; i < bmps.Length; i++)
  10141. {
  10142. this._bmps[i] = (Bitmap)bmps[i].Clone();
  10143. }
  10144. this._bmps_cut = new Mat[bmps_cut.Length];
  10145. for (int i = 0; i < bmps_cut.Length; i++)
  10146. {
  10147. this._bmps_cut[i] = bmps_cut[i].Clone();
  10148. }
  10149. this._x = Xmm;
  10150. this._y = Ymm;
  10151. this._info = info;
  10152. }
  10153. }
  10154. /// <summary>
  10155. /// 主窗体事件
  10156. /// </summary>
  10157. public class MainEventArgs : EventArgs
  10158. {
  10159. private string _tag;
  10160. public string Tag { get { return _tag; } }
  10161. private string _message;
  10162. public string Message { get { return _message; } }
  10163. private int _showIndex;
  10164. public int ShowIndex { get { return _showIndex; } }
  10165. private WarningEnum _warning;
  10166. public WarningEnum Warning { get { return _warning; } }
  10167. public MainEventArgs(int index)
  10168. {
  10169. this._showIndex = index;
  10170. }
  10171. public MainEventArgs(int index, string message)
  10172. {
  10173. this._message = message;
  10174. this._showIndex = index;
  10175. }
  10176. public MainEventArgs(string tag, string message, WarningEnum warning = WarningEnum.Normal)
  10177. {
  10178. this._tag = tag;
  10179. this._message = message;
  10180. this._showIndex = 0;
  10181. this._warning = warning;
  10182. }
  10183. }
  10184. /// <summary>
  10185. /// 初始化事件
  10186. /// </summary>
  10187. public class InitEventArgs : EventArgs
  10188. {
  10189. private string _message;
  10190. public string Message { get { return _message; } }
  10191. private bool _isInitialized;
  10192. public bool IsInitialized { get { return _isInitialized; } }
  10193. public InitEventArgs()
  10194. {
  10195. }
  10196. public InitEventArgs(string message, bool isInitialized = false)
  10197. {
  10198. this._message = message;
  10199. this._isInitialized = isInitialized;
  10200. }
  10201. }
  10202. #endregion
  10203. }