255 lines
11 KiB
C#
255 lines
11 KiB
C#
using MainShell.Common;
|
|
using MainShell.HeightMeasure.Model;
|
|
using MainShell.HeightMeasure.Service;
|
|
using MainShell.Log;
|
|
using MainShell.Models;
|
|
using MainShell.ProcessResult;
|
|
using MainShell.Recipe.Models;
|
|
using MainShell.Recipe.Models.SubstrateParameter;
|
|
using MW.WorkFlow;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace MainShell.Process
|
|
{
|
|
public class SubstrateHeightMeasureService
|
|
{
|
|
private readonly IHeightMeasure _heightMeasure;
|
|
private readonly HeightMeasureMotionService _heightMeasureMotionService;
|
|
|
|
public SubstrateHeightMeasureService(IHeightMeasure heightMeasure, HeightMeasureMotionService heightMeasureMotionService)
|
|
{
|
|
_heightMeasure = heightMeasure ?? throw new ArgumentNullException(nameof(heightMeasure));
|
|
_heightMeasureMotionService = heightMeasureMotionService ?? throw new ArgumentNullException(nameof(heightMeasureMotionService));
|
|
}
|
|
|
|
public async Task ExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
|
{
|
|
if (context == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(context));
|
|
}
|
|
|
|
if (activityControl == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(activityControl));
|
|
}
|
|
|
|
RecipeManager recipeManager = context.GetData<RecipeManager>(WorkflowContextKeys.RecipeManager);
|
|
ProcessResultManager processResultManager = context.GetData<ProcessResultManager>(WorkflowContextKeys.ProcessResultManager);
|
|
SubstrateRecipe substrateRecipe = GetCurrentRecipe(recipeManager);
|
|
IList<SubstrateHeightMeasurePoint> points = GetAvailablePoints(substrateRecipe);
|
|
SubstrateHeightMeasureProcessResult processResult = InitializeProcessResult(processResultManager, substrateRecipe.RecipeName);
|
|
|
|
try
|
|
{
|
|
LogManager.LogProcessInfo($"SubstrateHeightMeasure: start. Recipe={substrateRecipe.RecipeName}, PointCount={points.Count}");
|
|
|
|
for (int index = 0; index < points.Count; index++)
|
|
{
|
|
SubstrateHeightMeasurePoint point = points[index];
|
|
string pointName = GetPointName(point, index);
|
|
|
|
await CheckCancellationAndPauseAsync(activityControl).ConfigureAwait(false);
|
|
|
|
double positionX;
|
|
double positionY;
|
|
ResolveMeasurePosition(substrateRecipe, point, pointName, out positionX, out positionY);
|
|
|
|
LogManager.LogProcessDebug($"SubstrateHeightMeasure: moving to point[{index}] '{pointName}', X={positionX:F4}, Y={positionY:F4}");
|
|
_heightMeasureMotionService.MoveWaferMeasurePose(positionX, positionY);
|
|
|
|
double heightValue = _heightMeasure.GetDistance();
|
|
processResult.PointResults.Add(new SubstrateHeightMeasurePointResult
|
|
{
|
|
PointName = pointName,
|
|
RowIndex = point.RowIndex,
|
|
ColumnIndex = point.ColumnIndex,
|
|
PositionX = positionX,
|
|
PositionY = positionY,
|
|
HeightValue = heightValue
|
|
});
|
|
|
|
LogManager.LogProcessInfo($"SubstrateHeightMeasure: point[{index}] '{pointName}' measured height={heightValue:F4}");
|
|
}
|
|
|
|
processResult.IsSuccess = true;
|
|
processResult.ErrorMessage = null;
|
|
processResult.ErrorMessageKey = MessageKey.None;
|
|
processResult.ErrorMessageArguments = Array.Empty<string>();
|
|
LogManager.LogProcessInfo($"SubstrateHeightMeasure: completed. Recipe={substrateRecipe.RecipeName}, PointCount={processResult.PointResults.Count}");
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
processResult.IsSuccess = false;
|
|
processResult.ErrorMessage = null;
|
|
processResult.ErrorMessageKey = MessageKey.None;
|
|
processResult.ErrorMessageArguments = Array.Empty<string>();
|
|
LogManager.LogProcessInfo("SubstrateHeightMeasure: operation canceled.");
|
|
throw;
|
|
}
|
|
catch (LocalizedProcessException ex)
|
|
{
|
|
processResult.IsSuccess = false;
|
|
processResult.ErrorMessageKey = ex.FailureMessageKey;
|
|
processResult.ErrorMessageArguments = ex.FailureMessageArguments;
|
|
processResult.ErrorMessage = ex.Message;
|
|
LogManager.LogProcessError($"SubstrateHeightMeasure: {ex.Message}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
processResult.IsSuccess = false;
|
|
processResult.ErrorMessageKey = MessageKey.ProcessSubstrateHeightMeasureFailedWithReason;
|
|
processResult.ErrorMessageArguments = new string[] { ex.Message ?? string.Empty };
|
|
processResult.ErrorMessage = LanguageResourceHelper.Format(
|
|
processResult.ErrorMessageKey,
|
|
LocalizedProcessException.ConvertArguments(processResult.ErrorMessageArguments));
|
|
LogManager.LogProcessError($"SubstrateHeightMeasure: {processResult.ErrorMessage}");
|
|
}
|
|
finally
|
|
{
|
|
WriteResultToContext(context, processResultManager, processResult);
|
|
}
|
|
}
|
|
|
|
private static SubstrateRecipe GetCurrentRecipe(RecipeManager recipeManager)
|
|
{
|
|
if (recipeManager == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(recipeManager));
|
|
}
|
|
|
|
if (recipeManager.CurrentSubstrateRecipe == null)
|
|
{
|
|
throw new LocalizedProcessException(
|
|
MessageKey.ProcessSubstrateHeightMeasureRecipeNotLoaded,
|
|
Array.Empty<string>());
|
|
}
|
|
|
|
return recipeManager.CurrentSubstrateRecipe;
|
|
}
|
|
|
|
private static IList<SubstrateHeightMeasurePoint> GetAvailablePoints(SubstrateRecipe substrateRecipe)
|
|
{
|
|
if (substrateRecipe == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(substrateRecipe));
|
|
}
|
|
|
|
if (substrateRecipe.HeightMeasureSetting == null || substrateRecipe.HeightMeasureSetting.Points == null)
|
|
{
|
|
throw new LocalizedProcessException(
|
|
MessageKey.ProcessSubstrateHeightMeasureSettingMissing,
|
|
Array.Empty<string>());
|
|
}
|
|
|
|
List<SubstrateHeightMeasurePoint> points = new List<SubstrateHeightMeasurePoint>();
|
|
foreach (SubstrateHeightMeasurePoint point in substrateRecipe.HeightMeasureSetting.Points)
|
|
{
|
|
if (point != null)
|
|
{
|
|
points.Add(point);
|
|
}
|
|
}
|
|
|
|
if (points.Count == 0)
|
|
{
|
|
throw new LocalizedProcessException(
|
|
MessageKey.ProcessSubstrateHeightMeasureNoPoints,
|
|
Array.Empty<string>());
|
|
}
|
|
|
|
return points;
|
|
}
|
|
|
|
private static SubstrateHeightMeasureProcessResult InitializeProcessResult(ProcessResultManager processResultManager, string recipeName)
|
|
{
|
|
if (processResultManager == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(processResultManager));
|
|
}
|
|
|
|
SubstrateHeightMeasureProcessResult processResult = processResultManager.SubstrateHeightMeasureResult;
|
|
processResult.IsSuccess = false;
|
|
processResult.RecipeName = recipeName;
|
|
processResult.ErrorMessage = null;
|
|
processResult.ErrorMessageKey = MessageKey.None;
|
|
processResult.ErrorMessageArguments = Array.Empty<string>();
|
|
processResult.PointResults.Clear();
|
|
return processResult;
|
|
}
|
|
|
|
private static async Task CheckCancellationAndPauseAsync(ActivityControl activityControl)
|
|
{
|
|
activityControl.ThrowIfCancellationRequested();
|
|
await activityControl.CheckPauseAsync().ConfigureAwait(false);
|
|
}
|
|
|
|
private static void ResolveMeasurePosition(SubstrateRecipe substrateRecipe, SubstrateHeightMeasurePoint point, string pointName, out double positionX, out double positionY)
|
|
{
|
|
if (substrateRecipe == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(substrateRecipe));
|
|
}
|
|
|
|
if (point == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(point));
|
|
}
|
|
|
|
if (substrateRecipe.HeightMeasureSetting != null && substrateRecipe.HeightMeasureSetting.Mode == SubstrateHeightMeasureMode.RowColumnOffset)
|
|
{
|
|
if (substrateRecipe.SubstrateInfo == null || substrateRecipe.SubstrateInfo.PitchX <= 0 || substrateRecipe.SubstrateInfo.PitchY <= 0)
|
|
{
|
|
throw new LocalizedProcessException(
|
|
MessageKey.ProcessSubstrateHeightMeasurePointPositionInvalid,
|
|
pointName);
|
|
}
|
|
|
|
if (point.RowIndex <= 0 || point.ColumnIndex <= 0)
|
|
{
|
|
throw new LocalizedProcessException(
|
|
MessageKey.ProcessSubstrateHeightMeasurePointPositionInvalid,
|
|
pointName);
|
|
}
|
|
|
|
MPoint commonOffset = substrateRecipe.HeightMeasureSetting.CommonOffsetCompensation ?? new MPoint();
|
|
MPoint pointOffset = point.OffsetCompensation ?? new MPoint();
|
|
positionX = (point.ColumnIndex - 1) * substrateRecipe.SubstrateInfo.PitchX + commonOffset.X + pointOffset.X;
|
|
positionY = (point.RowIndex - 1) * substrateRecipe.SubstrateInfo.PitchY + commonOffset.Y + pointOffset.Y;
|
|
return;
|
|
}
|
|
|
|
if (point.TeachPosition == null)
|
|
{
|
|
throw new LocalizedProcessException(
|
|
MessageKey.ProcessSubstrateHeightMeasurePointPositionInvalid,
|
|
pointName);
|
|
}
|
|
|
|
positionX = point.TeachPosition.X;
|
|
positionY = point.TeachPosition.Y;
|
|
}
|
|
|
|
private static string GetPointName(SubstrateHeightMeasurePoint point, int index)
|
|
{
|
|
if (point == null || string.IsNullOrWhiteSpace(point.PointName))
|
|
{
|
|
return $"Point{index + 1}";
|
|
}
|
|
|
|
return point.PointName;
|
|
}
|
|
|
|
private static void WriteResultToContext(
|
|
WorkflowContext context,
|
|
ProcessResultManager processResultManager,
|
|
SubstrateHeightMeasureProcessResult processResult)
|
|
{
|
|
context.SetData(WorkflowContextKeys.SubstrateHeightMeasureResult, processResult);
|
|
processResultManager.SaveSubstrateHeightMeasureResult();
|
|
}
|
|
}
|
|
}
|