|
|
@@ -1562,6 +1562,103 @@ namespace TeamAAS_VP.Services
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 执行相机拍照并运行 ToolBlock,返回是否成功并通过 out 参数返回 Outputs、图像和图形集合。
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="procedure"></param>
|
|
|
+ /// <param name="InputTerminal"></param>
|
|
|
+ /// <param name="outputCollection"></param>
|
|
|
+ /// <param name="outImage"></param>
|
|
|
+ /// <param name="outGraphicCollection"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public bool ExecutePhotoEx(ProcedureModel procedure, Dictionary<string, string> InputTerminal, out CogToolBlockTerminalCollection outputCollection,out ICogImage outImage,out CogGraphicCollection outGraphicCollection)
|
|
|
+ {
|
|
|
+ outImage = null;
|
|
|
+ outGraphicCollection = null;
|
|
|
+ try
|
|
|
+ {
|
|
|
+
|
|
|
+ // 1. 采集图像
|
|
|
+ var camera = _cameraService.GetCamera(procedure.CameraId);
|
|
|
+ bool succed = camera.SetExposureTime(procedure.ExposureTime);
|
|
|
+ if (!succed)
|
|
|
+ {
|
|
|
+ SendTaskMessage($"相机曝光设置失败!", MessageLevel.Error);
|
|
|
+ }
|
|
|
+ succed = camera.SetGain(procedure.Gain);
|
|
|
+ if (!succed)
|
|
|
+ {
|
|
|
+ SendTaskMessage($"相机增益设置失败!", MessageLevel.Error);
|
|
|
+ }
|
|
|
+ DateTime nowtime = DateTime.Now;
|
|
|
+ LogHelper.WriteLogInfo("开始采集图像");
|
|
|
+ var image = camera.Grab();
|
|
|
+ if (image == null)
|
|
|
+ {
|
|
|
+
|
|
|
+ SendTaskMessage(Lang.图像采集失败, MessageLevel.Error);
|
|
|
+ outputCollection = null;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ outImage= image;
|
|
|
+ procedure.ToolBlock.Inputs["InputImage"].Value = image;
|
|
|
+ LogHelper.WriteLogInfo($"采集图像完成;用时:{(DateTime.Now - nowtime).Milliseconds}ms");
|
|
|
+
|
|
|
+ // 2. 为ToolBlock传入其他输入终端
|
|
|
+ if (InputTerminal != null)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogInfo($"为ToolBlock传入输入终端");
|
|
|
+ foreach (var item in InputTerminal)
|
|
|
+ {
|
|
|
+ if (procedure.ToolBlock.Inputs.Contains(item.Key))
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogInfo($"传入[{item.Key}]={item.Value}");
|
|
|
+ procedure.ToolBlock.Inputs[item.Key].Value = item.Value;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogInfo($"创建并传入[{item.Key}]={item.Value}");
|
|
|
+ procedure.ToolBlock.Inputs.Add(new CogToolBlockTerminal(item.Key, item.Value));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 运行视觉工具
|
|
|
+ LogHelper.WriteLogInfo("开始运行视觉工具");
|
|
|
+ procedure.ToolBlock.Run(); //运行ToolBlock
|
|
|
+
|
|
|
+ if (procedure.ToolBlock.RunStatus.Result == CogToolResultConstants.Accept)
|
|
|
+ {
|
|
|
+ SendTaskMessage(Lang.视觉流程执行耗时.Replace("{0}", procedure.Name).Replace("{1}", $"{procedure.ToolBlock.RunStatus.ProcessingTime:F1}"), MessageLevel.Info);
|
|
|
+ outputCollection = procedure.ToolBlock.Outputs; //获取输出终端集合
|
|
|
+ DatabaseHelper.AddCameraRecords(_productService.GetCurrentProduct().Name, procedure.Name, outputCollection);
|
|
|
+ ICogRecord record = null;
|
|
|
+ foreach (CogToolBlockTerminal item in outputCollection)
|
|
|
+ {
|
|
|
+ if (item.Value is ICogRecord)
|
|
|
+ record = item.Value as ICogRecord;
|
|
|
+ }
|
|
|
+ outGraphicCollection= outputCollection["Graphic"].Value as CogGraphicCollection;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ SendTaskMessage(Lang.视觉流程执行出错耗时.Replace("{0}", procedure.Name).Replace("{1}", $"{procedure.ToolBlock.RunStatus.ProcessingTime:F1}"), MessageLevel.Error);
|
|
|
+ SendTaskMessage(procedure.ToolBlock.RunStatus.Message, MessageLevel.Error);
|
|
|
+ outputCollection = null;
|
|
|
+ outGraphicCollection = outputCollection["Graphic"].Value as CogGraphicCollection;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ SendTaskMessage(ex.Message, MessageLevel.Error);
|
|
|
+ LogHelper.WriteLogError("执行相机取图并执行视觉工具组时出错!", ex);
|
|
|
+ outputCollection = null;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 执行相机拍照获取单个点位结果
|
|
|
/// </summary>
|
|
|
@@ -1639,6 +1736,86 @@ namespace TeamAAS_VP.Services
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// 执行相机拍照获取单个点位结果,并且返回图像和图形
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="procedure"></param>
|
|
|
+ /// <param name="InputTerminal"></param>
|
|
|
+ /// <param name="robotCoord"></param>
|
|
|
+ /// <param name="cancellationToken"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public async Task<(bool IsSucceed, double X, double Y, double U, ICogImage Image, CogGraphicCollection Graphic)> ExecutePhotoGetSinglePointWithImage(ProcedureModel procedure, Dictionary<string, string> InputTerminal, double[] robotCoord, CancellationToken cancellationToken)
|
|
|
+ {
|
|
|
+ DateTime nowtime = DateTime.Now;
|
|
|
+ await SetLightBeforePhoto(procedure);
|
|
|
+ ICogImage outImage=null;
|
|
|
+ CogGraphicCollection outGraphicCollection=null;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //拍照失败时,需要多次拍照
|
|
|
+ for (int i = 0; i < procedure.FeederFailLimit; i++)
|
|
|
+ {
|
|
|
+ SendTaskMessage(Lang.开始执行视觉流程.Replace("{0}", $"{i + 1}").Replace("{1}", procedure.Name), MessageLevel.Info);
|
|
|
+
|
|
|
+
|
|
|
+ // 1. 执行相机拍照并运行视觉工具
|
|
|
+ bool visionSucceed = ExecutePhotoEx(procedure, InputTerminal, out CogToolBlockTerminalCollection outputCollection, out outImage, out outGraphicCollection);
|
|
|
+ if (!visionSucceed)
|
|
|
+ {
|
|
|
+ SendTaskMessage(Lang.视觉任务执行失败, MessageLevel.Error);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!outputCollection.Contains("Found"))
|
|
|
+ {
|
|
|
+ SendTaskMessage(Lang.未找到视觉输出结果, MessageLevel.Error);
|
|
|
+ return (false, 0, 0, 0, outImage, outGraphicCollection);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 获取视觉输出结果
|
|
|
+ bool Found = (bool)(outputCollection["Found"].Value);
|
|
|
+ if (!Found)
|
|
|
+ {
|
|
|
+ SendTaskMessage(Lang.拍照NG, MessageLevel.Debug);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ SendTaskMessage(Lang.拍照OK, MessageLevel.Debug);
|
|
|
+
|
|
|
+ // 3. 获取视觉输出结果
|
|
|
+ LogHelper.WriteLogInfo("开始获取视觉输出结果");
|
|
|
+ //获取相机校准
|
|
|
+ var calib = _calibrationService.GetCalibration(procedure.CalibrationId);
|
|
|
+ string points = (string)(outputCollection["Point"].Value);
|
|
|
+ string[] strpoints = points.Split(';');
|
|
|
+ //先将pos按照逗号进行分隔,拿到数组
|
|
|
+ var posParts = strpoints[0].Split(',');
|
|
|
+ double _pixel_x = double.Parse(posParts[0]);
|
|
|
+ double _pixel_y = double.Parse(posParts[1]);
|
|
|
+ double _pixel_u = double.Parse(posParts[2]);
|
|
|
+ //转换点位-像素转换成机器人绝对坐标
|
|
|
+ var calibResult = _calibrationService.ConvertPixelToPosition((_pixel_x, _pixel_y, _pixel_u), robotCoord, calib, RobotBrand.XYZ_Platform);
|
|
|
+ if (!calibResult.IsSucceed)
|
|
|
+ {
|
|
|
+ return (false, 0, 0, 0, outImage, outGraphicCollection);
|
|
|
+ }
|
|
|
+ return (true, calibResult.X, calibResult.Y, calibResult.U, outImage, outGraphicCollection);
|
|
|
+ }
|
|
|
+ SendTaskMessage(Lang.多次拍照失败, MessageLevel.Alarm);
|
|
|
+ return (false, 0, 0, 0, outImage, outGraphicCollection);
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError("执行相机取图并获取单点位时出错!", ex);
|
|
|
+ return (false, 0, 0, 0, outImage, outGraphicCollection);
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await TurnOffLightAfterPhoto(procedure);
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 从 ToolBlock 的输出集合中根据 Procedure 配置提取需要发送的输出项并做必要的坐标转换。
|
|
|
/// 返回元组:是否成功、错误信息(失败时)和名称->(是否点位, 值) 的字典。
|