FitGirl游戏启动器:解决大型游戏存储难题的终极解决方案
2026/6/21 22:43:55
/// <summary>/// PLC通信模板/// </summary>/// <param name="ob"></param>privatevoidProcessPlcCommunication(objectob){// 无限循环:持续监听PLC信号,直到线程被终止while(true){try{// 仅当机器处于联机状态(_isOnline为true)时,才处理PLC通信if(_isOnline){// ========== 处理CCD1触发信号 ==========// 从keyencePlc1读取CCD1触发信号(Signal.SignalInput.CCD1Trigger是信号地址)intTrigger1=keyencePlc1.ReadInt16(Signal.SignalInput.CCD1Trigger).Content;//CCD1// 检测到CCD1触发(信号值为1)if(Trigger1==1){// 立即清零PLC的CCD1触发位(防止重复触发)keyencePlc1.Write(Signal.SignalInput.CCD1Trigger,0);LogNLog.Info("Receive CCD1Trigger------1");// 启动异步任务执行CCD1对应的检测逻辑(ProcessInsDockCam1),传入参数"1"Tasktask=newTask(ProcessInsDockCam1,"1");task.Start();}Thread.Sleep(5);// 5ms短延迟:避免信号读取过快导致的重复检测// ========== 处理CCD2触发信号 ==========// 从keyencePlc2读取CCD2触发信号intTrigger2=keyencePlc2.ReadInt16(Signal.SignalInput2.CCD2Trigger).Content;//CCD2if(Trigger2==1){keyencePlc2.Write(Signal.SignalInput2.CCD2Trigger,0);LogNLog.Info("Receive CCD2Trigger------1");Tasktask=newTask(ProcessInsDockCam2,"1");task.Start();}// ========== 处理CCD3触发信号(3D相机) ==========// 从keyencePlc2读取CCD3触发信号(mating面3D相机触发)intTrigger3=keyencePlc2.ReadInt16(Signal.SignalInput2.CCD3Trigger).Content;//CCD3if(Trigger3==1)//mating面3D相机触发{try{//清零keyencePlc2.Write(Signal.SignalInput2.CCD3Trigger,0);LogNLog.Info("Receive CCD3Trigger------1");//通知PLC已准备好----待定// keyencePlc2.Write(Signal.SignalInput2.CCD3Trigger, 0);// 原子操作设置3D相机触发标志位(ssznShotFlag)为1,避免多线程竞争Interlocked.Exchange(refssznShotFlag,1);// 启动3D激光相机扫描:参数来自配置表的Info数组(索引7和6)_laserSSZN.StartShot(Convert.ToInt16(_singleVppParamsTable3.visionInputParam.Info[7]),Convert.ToInt16(_singleVppParamsTable3.visionInputParam.Info[6]));// 通知PLC:启动3D扫描轴移动(写入信号CCD3DMove为1)keyencePlc2.Write(Signal.SignalOutput2.CCD3DMove,1);LogNLog.Info("请求PLC开始移动3D扫描轴--SendPLC-1");}catch(Exceptionex){// 3D相机触发异常:向PLC写入错误状态(CCD3nResult=2表示错误)keyencePlc2.Write(Signal.SignalOutput2.CCD3nResult,2);// 向PLC写入完成信号(CCD3Complete=1)keyencePlc2.Write(Signal.SignalOutput2.CCD3Complete,1);LogNLog.Error($"3D相机触发异常{ex.ToString()}");}}}else{LogNLog.Warn("机器未联机");}}catch(Exceptionex){LogNLog.Error("Server错误:"+ex.Source.ToString()+"接受信息:");}Thread.Sleep(100);}}/// <summary>/// 德创改机第一台CCD/// </summary>/// <param name="ob"></param>privatevoidProcessInsDockCam1(objectob){// 接收异步任务传入的参数(触发标识),转换为字符串stringreceiveData=string.Empty;receiveData=(string)ob;try{#region德创CCD1-2d// 判断触发参数为"1"(PLC触发CCD1检测)if(receiveData.Contains("1")){//开始计时LogNLog.Info($"CCD1:开始视觉检测");_stopWatch.Restart();// ========== 通用参数定义 ==========//通用参数修改区域stringcameraName="CCD1";stringtbName="外壳检测";stringstageDisName=$"外壳检测";// CCD1对应的参数表VppParamsDataTablesingleVppParamsTable=_singleVppParamsTable1;// ========== 光源控制 ==========// _frmDisplay.RecordInformation(stageDisName + "打开光源触发拍照");//光源打开_rs232.Write("SC0255#");LogNLog.Info("打开光源"+stageDisName+"触发拍照");// ========== 图像采集 ==========ICogImageimageLeft;// 存储采集的图像if(!GlobalsVar._isSimulateAcqImage){// 真实取图:调用视觉库的重试取图方法(最多重试3次)imageLeft=_cogVison.RunRetryAcq(CogVision._acqDealCollect[cameraName].Acq,3);}else{// 模拟取图(调试用):读取预设的模拟图片,在界面显示_frmDisplay.ShowSimulateImageIndex(tbName,GlobalsVar.simulateAcqImageInfoArr);imageLeft=_cogVison.ReadSimulateCogImage(tbName,GlobalsVar.simulateAcqImageInfoArr);}//关闭光源_rs232.Write("SC0000#");LogNLog.Info("关闭光源"+stageDisName+"取图完成");// ========== 空图判断(容错处理) ==========if(imageLeft==null){LogNLog.Error(stageDisName+"触发拍照为空,停止运行");// 向PLC写入:检测结果NG(2)+ 完成信号(1)keyencePlc1.Write(Signal.SignalOutput.CCD1Result,2);keyencePlc1.Write(Signal.SignalOutput.CCD1Complete,1);LogNLog.Error(stageDisName+$"触发拍照结果NG:{Signal.SignalOutput.CCD1Result}"+2+$" 完成信号:{Signal.SignalOutput.CCD1Complete}1"+" 处理时间:"+_stopWatch.ElapsedMilliseconds.ToString());return;}// ========== 视觉算法检测 ==========LogNLog.Info(stageDisName+"视觉处理");VisionInputParamvisionInputParam=newVisionInputParam();// 组装视觉检测输入参数:采集的图像 + 对应的算法工具块singleVppParamsTable.visionInputParam.InputImage=imageLeft;singleVppParamsTable.visionInputParam.ToolBlock=CogVision._toolBlockDealCollect[tbName].tool;visionInputParam=singleVppParamsTable.visionInputParam;// 运行视觉算法工具块,得到检测结果VisionResultvisionResult=_cogVison.RunToolBlock(visionInputParam);_ccd1Result=visionResult.Info;// 在界面显示检测后的图片和结果标志(OK / NG)_frmDisplay.ShowRecordImageNew(1,visionResult.ReCordImage,visionResult.Flag);// ========== 检测结果处理(OK) ==========if(visionResult.Flag||(singleVppParamsTable.visionInputParam.Info[5]=="1"?true:false)){// 向PLC写入:检测结果OK(1)+ 完成信号(1)keyencePlc1.Write(Signal.SignalOutput.CCD1Result,1);keyencePlc1.Write(Signal.SignalOutput.CCD1Complete,1);LogNLog.Info(stageDisName+$"触发拍照结果OK:{Signal.SignalOutput.CCD1Result}"+1+$" 完成信号:{Signal.SignalOutput.CCD1Complete}1"+" 处理时间:"+_stopWatch.ElapsedMilliseconds.ToString());#region主盘存图// 若配置为保存OK原图,将原图存入全局队列(OrginImageQueue)if(singleVppParamsTable.visionInputParam.IsSaveOKOriginal){ICogImageBuferimageBuffer=newICogImageBufer();imageBuffer.image=imageLeft;// 图片命名规则:产品名+文件夹名+结果+时间戳imageBuffer.name=$"Grey={_currentProductName}"+"="+singleVppParamsTable.visionInputParam.ImageFolderName+"="+"OK"+"="+DateTime.Now.ToString("yyyyMMddhhmmss");GlobalsVar.OrginImageQueue.Enqueue(imageBuffer);}// 若配置为保存OK截图if(singleVppParamsTable.visionInputParam.IsSaveOKScreen){RecordImageBuferbitmapBuffer=newRecordImageBufer();bitmapBuffer.record=_frmDisplay.SaveScreenimageArr(1);bitmapBuffer.name=$"{_currentProductName}"+"="+singleVppParamsTable.visionInputParam.ImageFolderName+"="+"OK"+"="+DateTime.Now.ToString("yyyyMMddhhmmss");GlobalsVar.ReocrdImageQueue.Enqueue(bitmapBuffer);}#endregion}// ========== 检测结果处理(NG) ==========else{// 向PLC写入:检测结果NG(2)+ 完成信号(1)keyencePlc1.Write(Signal.SignalOutput.CCD1Result,2);keyencePlc1.Write(Signal.SignalOutput.CCD1Complete,1);LogNLog.Error(stageDisName+$"触发拍照结果NG:{Signal.SignalOutput.CCD1Result}"+2+$" 完成信号:{Signal.SignalOutput.CCD1Complete}1"+" 处理时间:"+_stopWatch.ElapsedMilliseconds.ToString());#region主盘存图//保存NG原图if(singleVppParamsTable.visionInputParam.IsSaveNGOriginal){ICogImageBuferimageBuffer=newICogImageBufer();imageBuffer.image=imageLeft;imageBuffer.name=$"Grey={_currentProductName}"+"="+singleVppParamsTable.visionInputParam.ImageFolderName+"="+"NG"+"="+DateTime.Now.ToString("yyyyMMddhhmmss");GlobalsVar.OrginImageQueue.Enqueue(imageBuffer);}// 保存NG截图if(singleVppParamsTable.visionInputParam.IsSaveNGScreen){RecordImageBuferbitmapBuffer=newRecordImageBufer();bitmapBuffer.record=_frmDisplay.SaveScreenimageArr(1);bitmapBuffer.name=$"{_currentProductName}"+"="+singleVppParamsTable.visionInputParam.ImageFolderName+"="+"NG"+"="+DateTime.Now.ToString("yyyyMMddhhmmss");GlobalsVar.ReocrdImageQueue.Enqueue(bitmapBuffer);}#endregion}//还要加个屏蔽信号}#endregion#region内存优化_gcCount++;if(_gcCount>6){_stopWatchFlush.Restart();_gcCount=0;FlushMemory();LogNLog.Info("内存优化");LogNLog.Info("内存优化处理时间:"+_stopWatchFlush.ElapsedMilliseconds.ToString());}#endregion}catch(Exceptionex){keyencePlc1.Write(Signal.SignalOutput.CCD1Result,2);keyencePlc1.Write(Signal.SignalOutput.CCD1Complete,1);LogNLog.Error("CCD1检测跳到异常:"+$"触发拍照结果NG:{Signal.SignalOutput.CCD1Result}"+2+$" 完成信号:{Signal.SignalOutput.CCD1Complete}1"+" 处理时间:"+_stopWatch.ElapsedMilliseconds.ToString());LogNLog.Error(ex.ToString());}}