using JM1Vision; using MainShell.Common; using MainShell.Log; using MainShell.Vision.Common; using MwFramework.Device; using MwFramework.Device.Model; using MwFramework.ManagerService; using SemiconductorVisionAlgorithm.SemiCalib; using SemiconductorVisionAlgorithm.SemiParams; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using System.Windows; using Jm1RecheckDiePoint = JM1.JM1Params.RecheckDiePoint; using SemiPoint = SemiconductorVisionAlgorithm.SemiParams.Point; namespace MainShell.Vision { /// /// 通用视觉算法服务。 /// public class CommonVisionAlgorithmService : ICommonVisionAlgorithmService { public Task GenWaferMapXAsync( string fileDirectory, double[] edgePtRow, double[] edgePtCol, double[] edgePtAngle, double[] inPtRow, double[] inPtCol, double[] inPtAngle, double upThresholdAngle, double upRowDistance, double upColDistance, int upRowNumber, int upColNumber, double firstPosRow, double firstPosCol, double distanceThreshold, double angleThreshold, double rotateAngle, CancellationToken cancellationToken = default(CancellationToken)) { return ExecuteBoolAlgorithmAsync( nameof(GenWaferMapXAsync), delegate () { return JM1Manager.Instance.gen_wafer_map_x( fileDirectory, edgePtRow, edgePtCol, edgePtAngle, inPtRow, inPtCol, inPtAngle, upThresholdAngle, upRowDistance, upColDistance, upRowNumber, upColNumber, firstPosRow, firstPosCol, distanceThreshold, angleThreshold, rotateAngle); }, cancellationToken); } public Task RecheckPosRgbAsync( List edgeDiePoints, List inDiePoints, double threshold, List existingPoints, RecheckDieMap padPos, double diePitch, int rowNumber, int colNumber, CancellationToken cancellationToken = default(CancellationToken)) { return ExecuteBoolAlgorithmAsync( nameof(RecheckPosRgbAsync), delegate () { Dictionary> rawPadPos = padPos; return JM1Manager.Instance.recheck_posRGB( edgeDiePoints, inDiePoints, threshold, existingPoints, rawPadPos, diePitch, rowNumber, colNumber); }, cancellationToken); } public Task ClearRecheckDiePosAsync( CancellationToken cancellationToken = default(CancellationToken)) { return ExecuteBoolAlgorithmAsync( nameof(ClearRecheckDiePosAsync), delegate () { return JM1Manager.Instance.ClearRecheckdiepos(); }, cancellationToken); } public Task ClearMapAsync( int flag, CancellationToken cancellationToken = default(CancellationToken)) { return ExecuteBoolAlgorithmAsync( nameof(ClearMapAsync), delegate () { return JM1Manager.Instance.ClearMap(flag); }, cancellationToken); } public Task PatchPos, List ExceptPos)>> GetMapAsync( CancellationToken cancellationToken = default(CancellationToken)) { return ExecuteDataAlgorithmAsync( nameof(GetMapAsync), delegate () { Dictionary> upMap; List patchPos; List exceptPos; bool executeResult = JM1Manager.Instance.GetMap(out upMap, out patchPos, out exceptPos); EnsureExecutionSucceeded(nameof(GetMapAsync), executeResult); return (new RecheckDieMap(upMap), patchPos, exceptPos); }, cancellationToken); } public Task ExposedPoints)>> GetRecheckDiePosAsync( CancellationToken cancellationToken = default(CancellationToken)) { return ExecuteDataAlgorithmAsync( nameof(GetRecheckDiePosAsync), delegate () { Dictionary> map; List exposedPoints; bool executeResult = JM1Manager.Instance.GetRecheckdiepos(out map, out exposedPoints); EnsureExecutionSucceeded(nameof(GetRecheckDiePosAsync), executeResult); return (new RecheckDieMap(map), exposedPoints); }, cancellationToken); } public Task CalProductAffineAsync( List sourcePoints, List targetPoints, CancellationToken cancellationToken = default(CancellationToken)) { return ExecuteBoolAlgorithmAsync( nameof(CalProductAffineAsync), delegate () { return JM1Manager.Instance.cal_product_affine(sourcePoints, targetPoints); }, cancellationToken); } public Task> CalculateLineAngleAsync( SemiPoint point1, SemiPoint point2, CancellationToken cancellationToken = default(CancellationToken)) { return ExecuteDataAlgorithmAsync( nameof(CalculateLineAngleAsync), delegate () { double deg; bool executeResult = JM1Manager.Instance.calculate_line_angle(point1, point2, out deg); EnsureExecutionSucceeded(nameof(CalculateLineAngleAsync), executeResult); return deg; }, cancellationToken); } public Task SetWorkAreaAsync( string fileDirectory, double heightY, double widthX, CancellationToken cancellationToken = default(CancellationToken)) { return ExecuteBoolAlgorithmAsync( nameof(SetWorkAreaAsync), delegate () { return JM1Manager.Instance.set_workarea(fileDirectory, heightY, widthX); }, cancellationToken); } public Task SetDirectionAsync( string fileDirectory, int xDirection, int yDirection, CancellationToken cancellationToken = default(CancellationToken)) { return ExecuteBoolAlgorithmAsync( nameof(SetDirectionAsync), delegate () { return JM1Manager.Instance.set_direction(fileDirectory, xDirection, yDirection); }, cancellationToken); } private static Task ExecuteBoolAlgorithmAsync( string algorithmName, Func execute, CancellationToken cancellationToken) { if (execute == null) { throw new ArgumentNullException(nameof(execute)); } try { cancellationToken.ThrowIfCancellationRequested(); bool executeResult = execute(); EnsureExecutionSucceeded(algorithmName, executeResult); string message = $"CommonVisionAlgorithmService: algorithm {algorithmName} completed."; message.LogInfo(); return Task.FromResult(VisionProcessResult.Success()); } catch (OperationCanceledException ex) { string message = $"CommonVisionAlgorithmService: algorithm {algorithmName} was cancelled."; message.LogInfo(); return Task.FromResult(VisionProcessResult.Failure( VisionFailureCategory.Cancelled, VisionErrorCode.OperationCancelled, null, MessageKey.VisionOperationCancelled, message, ex)); } catch (Exception ex) { string message = $"CommonVisionAlgorithmService: algorithm {algorithmName} failed. {ex.Message}"; message.LogSysError(); return Task.FromResult(VisionProcessResult.Failure( VisionFailureCategory.Algorithm, VisionErrorCode.CommonAlgorithmExecutionFailed, VisionAlarmIds.CommonAlgorithmExecutionFailed, MessageKey.VisionCommonAlgorithmExecutionFailed, message, ex)); } } private static Task> ExecuteDataAlgorithmAsync( string algorithmName, Func execute, CancellationToken cancellationToken) { if (execute == null) { throw new ArgumentNullException(nameof(execute)); } try { cancellationToken.ThrowIfCancellationRequested(); TData result = execute(); string message = $"CommonVisionAlgorithmService: algorithm {algorithmName} completed."; message.LogInfo(); return Task.FromResult(VisionProcessResult.Success(result)); } catch (OperationCanceledException ex) { string message = $"CommonVisionAlgorithmService: algorithm {algorithmName} was cancelled."; message.LogInfo(); return Task.FromResult(VisionProcessResult.Failure( VisionFailureCategory.Cancelled, VisionErrorCode.OperationCancelled, null, MessageKey.VisionOperationCancelled, message, ex)); } catch (Exception ex) { string message = $"CommonVisionAlgorithmService: algorithm {algorithmName} failed. {ex.Message}"; message.LogSysError(); return Task.FromResult(VisionProcessResult.Failure( VisionFailureCategory.Algorithm, VisionErrorCode.CommonAlgorithmExecutionFailed, VisionAlarmIds.CommonAlgorithmExecutionFailed, MessageKey.VisionCommonAlgorithmExecutionFailed, message, ex)); } } private static void EnsureExecutionSucceeded(string algorithmName, bool executeResult) { if (!executeResult) { throw new InvalidOperationException($"CommonVisionAlgorithmService: algorithm {algorithmName} returned false."); } } } }