| | |
| | | using Bro.Common.Helper; |
| | | using Bro.Common.Interface; |
| | | using Bro.Common.Model; |
| | | using Bro.M071.DBManager; |
| | | using Bro.M071.Model; |
| | | using Bro.M071.Model.Model; |
| | | using Bro.M071.Process.UI; |
| | | using Bro.Process; |
| | | using HalconDotNet; |
| | | using Newtonsoft.Json; |
| | |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel; |
| | | using System.Drawing; |
| | | using System.Drawing.Imaging; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using System.Text; |
| | |
| | | |
| | | base.Open(); |
| | | |
| | | InitialMotionCardBaseAxisAlarm(); |
| | | |
| | | SwitchBeep(false); |
| | | SwitchLightGreen(false); |
| | | SwitchLightRed(false); |
| | |
| | | |
| | | Reset(null, null, null); |
| | | FullReset(null); |
| | | |
| | | } |
| | | |
| | | private void InitialMotionCardBaseAxisAlarm() |
| | | { |
| | | if (outputCtrlCard != null) |
| | | { |
| | | outputCtrlCard.OnAxisAlarmRaised -= MotionCard_OnAxisAlarmRaised; |
| | | outputCtrlCard.OnAxisAlarmRaised += MotionCard_OnAxisAlarmRaised; |
| | | } |
| | | } |
| | | |
| | | private void MotionCard_OnAxisAlarmRaised(int axisIndex, string alarmMsg) |
| | | { |
| | | RaisedAlarm(alarmMsg); |
| | | MachineState = MachineState.Alarm; |
| | | } |
| | | |
| | | private void InitialSetting() |
| | | { |
| | | ////数据库迁移检查 |
| | | //DatabaseInitialize.Initialize(); |
| | | //数据库迁移检查 |
| | | DatabaseInitialize.Initialize(); |
| | | |
| | | MotionCardSettingCheck(); |
| | | |
| | |
| | | [ProcessMethod("", "StartJob", "开始扫描", InvokeType.TestInvoke)] |
| | | public ProcessResponse StartJob(IOperationConfig opConfig, IDevice invokeDevice, IDevice sourceDevice) |
| | | { |
| | | if (!IsAllowedWork) |
| | | { |
| | | throw new ProcessException(SafetyMsg, null, ExceptionLevel.Fatal); |
| | | } |
| | | |
| | | if (MachineState != MachineState.Ready) |
| | | throw new ProcessException("机台未就绪,请勿开始测量", null, ExceptionLevel.Fatal); |
| | | |
| | |
| | | Config.SnapshotPointCollection.Where(u => u.IsEnabled).ToList().ForEach(s => |
| | | { |
| | | _pauseHandle.WaitHandle.WaitOne(); |
| | | |
| | | if (MachineState != MachineState.Running) |
| | | { |
| | | throw new ProcessException("机台状态不在运行中,退出检测"); |
| | | } |
| | | |
| | | IDevice device = DeviceCollection.FirstOrDefault(u => u.Id == s.MotionOp.Device); |
| | | if (device == null) |
| | |
| | | |
| | | LogAsync(DateTime.Now, $"{m.GetDisplayText()}检测结果", $"{((m.Spec.MeasureResult ?? false) ? "OK" : "NG")}"); |
| | | |
| | | IShapeElement indicator = null; |
| | | KeyIndicator indicator = new KeyIndicator(m.Id, m.DisplayLocation); |
| | | indicator.Text = (m.Spec.ActualValue == null || m.Spec.ActualValue == -999) ? "NA" : m.Spec.ActualValue.Value.ToString("f2"); |
| | | indicator.ResultState = m.Spec.MeasureResult; |
| | | pMeasure.ElementList.Add(indicator); |
| | | //输出图形基元到界面 |
| | | OnElementUpdated?.BeginInvoke(indicator, null, null); |
| | |
| | | |
| | | pMeasure.EndTime = DateTime.Now; |
| | | bool pResult = pMeasure.Measurements.All(u => u.Spec.MeasureResult == true); |
| | | pMeasure.PResult = pResult ? "OK" : "NG"; |
| | | OnUpdateResult?.Invoke(DateTime.Now, pResult ? 1 : 0); |
| | | OnUpdateCT?.Invoke((float)(pMeasure.EndTime.Value - pMeasure.StartTime.Value).TotalSeconds); |
| | | |
| | | LogAsync(DateTime.Now, $"{pMeasure.Barcode} 检测完成,结果 {(pResult ? "OK" : "NG")}", ""); |
| | | LogAsync(DateTime.Now, $"{pMeasure.Barcode} 检测完成,结果 {pMeasure.PResult}", ""); |
| | | |
| | | if (MachineState == MachineState.Running) |
| | | MachineState = MachineState.Ready; |
| | | |
| | | var measurementUnitResultAndKeyUnitDataSet = GetMeasurementUnitResultAndKeyUnitData(pMeasure); |
| | | |
| | | //MES输出 todo |
| | | if (Config.IsEnableMESUpload) |
| | | { |
| | | } |
| | | |
| | | //Excel报表输出 todo |
| | | |
| | | //数据库保存 todo |
| | | ////Excel报表输出 (单个产品的excel导出) |
| | | //ExportProductionExcel(measurementUnitResultAndKeyUnitDataSet); |
| | | ////数据库保存 |
| | | //SaveProductionData(measurementUnitResultAndKeyUnitDataSet); |
| | | |
| | | SaveWholeImage(pMeasure); |
| | | |
| | | productionList.RemoveAll(p => p.Barcode == pMeasure.Barcode); |
| | | pMeasure.Dispose(); |
| | | } |
| | | } |
| | | |
| | | KeyUnitDataManager keyUnitDataManager = new KeyUnitDataManager(); |
| | | MeasurementUnitResultManager measurementUnitResultManager = new MeasurementUnitResultManager(); |
| | | MeasurementAndKeyDataRelationManager measurementAndKeyDataRelationManager = new MeasurementAndKeyDataRelationManager(); |
| | | ProductionMeasurementRecordsManager productionMeasurementRecordsManager = new ProductionMeasurementRecordsManager(); |
| | | |
| | | static object dataSaveLock = new object(); |
| | | |
| | | private async void SaveProductionData(ProductionMeasurementUnitResultAndKeyUnitDataSet measurementUnitResultAndKeyUnitDataSet) |
| | | { |
| | | await Task.Run(() => |
| | | { |
| | | try |
| | | { |
| | | lock (dataSaveLock) |
| | | { |
| | | // 获取 产品数据 并保存 |
| | | var productionMeasurementRecords = measurementUnitResultAndKeyUnitDataSet.ProductionMeasurementRecord; |
| | | productionMeasurementRecordsManager.CreateModel(productionMeasurementRecords); |
| | | |
| | | // 获取 原始数据 并保存 |
| | | var keyUnitDatas = measurementUnitResultAndKeyUnitDataSet.KeyUnitDataList; |
| | | keyUnitDataManager.BatchAddKeyUnitData(keyUnitDatas); |
| | | |
| | | // 获取 检测结果数据 并保存 |
| | | var measurementUnitResults = measurementUnitResultAndKeyUnitDataSet.MeasurementUnitResultList; |
| | | measurementUnitResultManager.BatchAddMeasurementUnitResult(measurementUnitResults); |
| | | |
| | | // 获取 关系数据并保存 |
| | | var measurementAndKeyDataRelationList = measurementUnitResultAndKeyUnitDataSet.MeasurementAndKeyDataRelationList; |
| | | measurementAndKeyDataRelationManager.BatchAddMeasurementAndKeyDataRelation(measurementAndKeyDataRelationList); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogAsync(DateTime.Now, "数据保存异常", ex.GetExceptionMessage()); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | private ProductionMeasurementUnitResultAndKeyUnitDataSet GetMeasurementUnitResultAndKeyUnitData(ProductionMeasurement pData) |
| | | { |
| | | ProductionMeasurementUnitResultAndKeyUnitDataSet measurementUnitResultAndKeyUnitDataSet = new ProductionMeasurementUnitResultAndKeyUnitDataSet(); |
| | | |
| | | try |
| | | { |
| | | |
| | | //产品数据 |
| | | ProductionMeasurementRecords productionMeasurementRecords = new ProductionMeasurementRecords(); |
| | | //关系数据 |
| | | List<MeasurementAndKeyDataRelation> measurementAndKeyDataRelationList = new List<MeasurementAndKeyDataRelation>(); |
| | | //原始数据 |
| | | List<KeyUnitData> keyUnitDatas = new List<KeyUnitData>(); |
| | | // 单个产品的测量汇总 |
| | | List<MeasurementUnitResult> measurementUnitResults = new List<MeasurementUnitResult>(); |
| | | |
| | | productionMeasurementRecords.ProductionBarcode = pData.Barcode; |
| | | productionMeasurementRecords.ProductionCode = ProductionCode; |
| | | productionMeasurementRecords.ProductionResult = pData.PResult; |
| | | productionMeasurementRecords.OperationStartTime = pData.StartTime.GetValueOrDefault(); |
| | | productionMeasurementRecords.OperationEndTime = pData.EndTime.GetValueOrDefault(); |
| | | |
| | | measurementUnitResultAndKeyUnitDataSet.ProductionMeasurementRecord = productionMeasurementRecords; |
| | | |
| | | foreach (var measurementUnit in pData.Measurements)//获取到单个测量项结果 |
| | | { |
| | | MeasurementUnitResult measurementUnitResult = new MeasurementUnitResult(); |
| | | measurementUnitResult.ProductionMeasurementRecordsId = productionMeasurementRecords.ID; |
| | | measurementUnitResult.MeasurementName = measurementUnit.Name; |
| | | measurementUnitResult.MeasurementType = measurementUnit.MeasureType; |
| | | measurementUnitResult.MeasurementValue = measurementUnit.Spec.ActualValue.ToString(); |
| | | measurementUnitResult.MeasurementResult = measurementUnit.Spec.MeasureResult.Value ? "OK" : "NG"; |
| | | |
| | | measurementUnitResults.Add(measurementUnitResult); |
| | | |
| | | foreach (var keyUnit in measurementUnit.KeyUnitCollection)//获取单个键的测量结果 |
| | | { |
| | | foreach (var keyValue in keyUnit.MeasureValueDict)//获取单个键的单个测量item 结果 |
| | | { |
| | | bool isExist = keyUnitDatas.Any(u => u.Key == keyUnit.Key && u.MeasurementItem == keyValue.Key); |
| | | if (!isExist)//已存在 不重复添加原始数据 |
| | | { |
| | | KeyUnitData keyUnitData = new KeyUnitData(); |
| | | keyUnitData.Key = keyUnit.Key; |
| | | keyUnitData.MeasurementItem = keyValue.Key; |
| | | keyUnitData.ItemValue = keyValue.Value.ToString(); |
| | | keyUnitDatas.Add(keyUnitData); |
| | | |
| | | MeasurementAndKeyDataRelation measurementAndKeyDataRelation = new MeasurementAndKeyDataRelation(); |
| | | measurementAndKeyDataRelation.MeasurementUnitResultId = measurementUnitResult.ID; |
| | | measurementAndKeyDataRelation.KeyUnitDataId = keyUnitData.ID; |
| | | measurementAndKeyDataRelationList.Add(measurementAndKeyDataRelation); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | measurementUnitResultAndKeyUnitDataSet.ProductionMeasurementRecord = productionMeasurementRecords; |
| | | measurementUnitResultAndKeyUnitDataSet.MeasurementAndKeyDataRelationList = measurementAndKeyDataRelationList; |
| | | measurementUnitResultAndKeyUnitDataSet.KeyUnitDataList = keyUnitDatas; |
| | | measurementUnitResultAndKeyUnitDataSet.MeasurementUnitResultList = measurementUnitResults; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogAsync(DateTime.Now, "数据获取异常", ex.GetExceptionMessage()); |
| | | } |
| | | return measurementUnitResultAndKeyUnitDataSet; |
| | | } |
| | | |
| | | private async void ExportProductionExcel(ProductionMeasurementUnitResultAndKeyUnitDataSet measurementUnitResultAndKeyUnitDataSet) |
| | | { |
| | | if (!Config.IsCSVOutputEnabled) |
| | | return; |
| | | |
| | | await Task.Run(() => |
| | | { |
| | | ExcelExportSet excelExportDto = new ExcelExportSet(); |
| | | excelExportDto.Worksheets = new List<string>() { "原始数据", "检测结果" }; |
| | | var keyUnitColumns = new Dictionary<string, string>() |
| | | { |
| | | {"Key", "键"}, |
| | | {"MeasurementItem", "检测项"}, |
| | | {"ItemValue", "检测值"} |
| | | }; |
| | | var measurementUnitResultColumns = new Dictionary<string, string>() |
| | | { |
| | | {"MeasurementName", "检测名称"}, |
| | | {"MeasurementType", "检测类型"}, |
| | | {"MeasurementValue", "检测值"}, |
| | | {"MeasurementResult", "检测结果"}, |
| | | }; |
| | | excelExportDto.WorksheetColumns[excelExportDto.Worksheets[0]] = keyUnitColumns; |
| | | excelExportDto.WorksheetColumns[excelExportDto.Worksheets[1]] = measurementUnitResultColumns; |
| | | |
| | | excelExportDto.WorksheetDataTable[excelExportDto.Worksheets[0]] = ExcelExportHelper.ListToDataTable(measurementUnitResultAndKeyUnitDataSet.KeyUnitDataList, keyUnitColumns); |
| | | excelExportDto.WorksheetDataTable[excelExportDto.Worksheets[1]] = ExcelExportHelper.ListToDataTable(measurementUnitResultAndKeyUnitDataSet.MeasurementUnitResultList, measurementUnitResultColumns); ; |
| | | |
| | | string dir = Path.Combine(Config.LogPath, DateTime.Now.ToString("yyyyMMdd")); |
| | | if (!Directory.Exists(dir)) |
| | | { |
| | | Directory.CreateDirectory(dir); |
| | | } |
| | | var fileName = Path.Combine(dir, $"{measurementUnitResultAndKeyUnitDataSet.ProductionMeasurementRecord.ProductionBarcode}_{DateTime.Now.ToString("HHmmss")}.xlsx"); |
| | | |
| | | byte[] filecontent = ExcelExportHelper.CreateOrAppendExcel(excelExportDto, fileName); |
| | | FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write); |
| | | fs.Write(filecontent, 0, filecontent.Length); |
| | | fs.Flush(); |
| | | fs.Close(); |
| | | }); |
| | | } |
| | | |
| | | #region 图像保存 |
| | |
| | | Directory.CreateDirectory(dir); |
| | | } |
| | | |
| | | map.Save(Path.Combine(dir, $"{pMeasure.Barcode}_{DateTime.Now.ToString("HHmmss")}.bmp")); |
| | | map.Save(Path.Combine(dir, $"{pMeasure.Barcode}_{pMeasure.PResult}_{DateTime.Now.ToString("HHmmss")}.png"), ImageFormat.Png); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | int i = 0; |
| | | u.KeyImages?.ForEach(image => |
| | | { |
| | | string fileName = Path.Combine(dir, $"{measureName}_{u.Key}{(i == 0 ? "" : $"-{i}")}_{DateTime.Now.ToString("HHmmss")}.tiff"); |
| | | image.WriteImage("tiff", 0, fileName); |
| | | string fileName = ""; |
| | | try |
| | | { |
| | | fileName = Path.Combine(dir, $"{measureName}_{u.Key}{(i == 0 ? "" : $"-{i}")}_{DateTime.Now.ToString("HHmmss")}.tiff"); |
| | | image.WriteImage("tiff", 0, fileName); |
| | | } |
| | | catch (Exception) |
| | | { |
| | | LogAsync(DateTime.Now, "切图保存失败", fileName); |
| | | } |
| | | i++; |
| | | }); |
| | | |
| | |
| | | string toolKey = (opConfig as CameraOprerationConfigBase).AlgorithemPath; |
| | | HObject images = imgSet.HImage; |
| | | LaserScanParam scanParam = JsonConvert.DeserializeObject<LaserScanParam>(imgSet.ImageData); |
| | | LogAsync(DateTime.Now, $"扫描参数:{imgSet.ImageData}", ""); |
| | | |
| | | if (!string.IsNullOrWhiteSpace(toolKey)) |
| | | { |
| | |
| | | } |
| | | |
| | | HOperatorSet.CountObj(images, out HTuple count); |
| | | LogAsync(DateTime.Now, $"{snapshotName}切图{count.I}张", ""); |
| | | |
| | | if (count == 0) |
| | | { |
| | |
| | | return; |
| | | } |
| | | |
| | | var excludeKeys = keys.Where(u => u.ImageSeq > count).ToList(); |
| | | var excludeKeys = keys.Where(u => u.ImageSeq > count.I).ToList(); |
| | | if (excludeKeys.Count > 0) |
| | | { |
| | | LogAsync(DateTime.Now, $"{string.Join(" ", excludeKeys.Select(u => u.AliasName))}未在图片获取序列中", ""); |
| | |
| | | }); |
| | | } |
| | | |
| | | Parallel.For(1, count.I, (i) => |
| | | string dir = Path.Combine(Config.ImageSaveFolder, "Clips", $"{snapshotName}_{DateTime.Now.ToString("HHmmss")}"); |
| | | if (!Directory.Exists(dir)) |
| | | { |
| | | Directory.CreateDirectory(dir); |
| | | } |
| | | |
| | | Parallel.For(1, count.I + 1, (i) => |
| | | //for (int i = 1; i <= count.I; i++) |
| | | { |
| | | HOperatorSet.SelectObj(images, out HObject image, i); |
| | | |
| | | string fileName = Path.Combine(dir, $"{i}.tif"); |
| | | image.ConvertHObjectToHImage().WriteImage("tiff", 0, fileName); |
| | | |
| | | keys.Where(u => u.ImageSeq == i).ToList().ForEach(k => |
| | | { |
| | |
| | | else |
| | | { |
| | | _halconToolDict[keyToolKey].InputImageDic["INPUT_Image"] = image; |
| | | _halconToolDict[keyToolKey].InputTupleDic["INPUT_Resolution_X"] = scanParam.Resolution_X; |
| | | _halconToolDict[keyToolKey].InputTupleDic["INPUT_Resolution_Z"] = scanParam.Resolution_Z; |
| | | _halconToolDict[keyToolKey].InputTupleDic["INPUT_Resolution_X"] = scanParam.Resolution_X / 1000000.0; |
| | | _halconToolDict[keyToolKey].InputTupleDic["INPUT_Resolution_Z"] = scanParam.Resolution_Z / 1000000.0; |
| | | if (!_halconToolDict[keyToolKey].RunProcedure(out string error)) |
| | | { |
| | | LogAsync(DateTime.Now, $"{k.AliasName}检测算法异常,{error}", ""); |
| | |
| | | |
| | | keyBindList.ForEach(kb => |
| | | { |
| | | kb.KeyImages.Add(image.Clone() as HImage); |
| | | kb.KeyImages.Add(image.ConvertHObjectToHImage()); |
| | | kb.FillKeyValues(resultDict); |
| | | }); |
| | | }); |
| | | |
| | | image.Dispose(); |
| | | }); |
| | | //image.Dispose(); |
| | | } |
| | | ); |
| | | |
| | | //if (count.I != 1) |
| | | //{ |