Files

214 lines
8.9 KiB
C#
Raw Permalink Normal View History

using MainShell.Common;
using MainShell.DeviceMaintance.Model;
using MainShell.Hardware;
using MainShell.Motion;
using MainShell.Parameter;
using MainShell.ParaSetting.Model;
using MaxwellFramework.Core.Attributes;
using MaxwellFramework.Core.Interfaces;
using MW.WorkFlow;
using MwFramework.ManagerService;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace MainShell.Process
{
[Singleton]
public class NeedleZCalibrationService
{
private const double Precision = 0.001;
private readonly HardwareManager _hardwareManager;
private readonly SafeAxisMotion _safeAxisMotion;
private readonly IParamList _paramList;
private readonly IDeviceIoMonitorService _deviceIoMonitorService;
public NeedleZCalibrationService(HardwareManager hardwareManager, SafeAxisMotion safeAxisMotion, IParameterManager parameterManager, IDeviceIoMonitorService deviceIoMonitorService)
{
_hardwareManager = hardwareManager ?? throw new ArgumentNullException(nameof(hardwareManager));
_safeAxisMotion = safeAxisMotion ?? throw new ArgumentNullException(nameof(safeAxisMotion));
_paramList = parameterManager as IParamList;
_deviceIoMonitorService = deviceIoMonitorService ?? throw new ArgumentNullException(nameof(deviceIoMonitorService));
}
public NeedleZCalibrationExecutionContext GetExecutionContext(int? inputTouchCount, bool? inputAutoRaiseZ1)
{
NeedleCalibrationSetting needleCalibrationSetting = _paramList?.GetParameter<NeedleCalibrationSetting>();
EquipmentParaSysSetting equipmentParaSysSetting = _paramList?.GetParameter<EquipmentParaSysSetting>();
return CreateExecutionContext(needleCalibrationSetting, equipmentParaSysSetting, inputTouchCount, inputAutoRaiseZ1);
}
public NeedleZCalibrationExecutionContext CreateExecutionContext(NeedleCalibrationSetting needleCalibrationSetting, EquipmentParaSysSetting equipmentParaSysSetting, int? inputTouchCount, bool? inputAutoRaiseZ1)
{
ValidateCalibrationSetting(needleCalibrationSetting);
NeedleZCalibrationItem item = needleCalibrationSetting.NeedleZCalibrationItem;
ValidateCalibrationItem(item);
int touchCount = Math.Max(1, inputTouchCount ?? item.NeedleTouchCount);
bool autoRaiseZ1 = inputAutoRaiseZ1 ?? true;
double safeHeight = ResolveSafeHeight(equipmentParaSysSetting);
return new NeedleZCalibrationExecutionContext(needleCalibrationSetting, item, touchCount, autoRaiseZ1, safeHeight);
}
public async Task<double> ExecuteSingleTouchAsync(bool autoRaiseZ1, CancellationToken cancellationToken)
{
return await ExecuteSingleTouchAsync(autoRaiseZ1, cancellationToken, null);
}
public async Task<double> ExecuteSingleTouchAsync(bool autoRaiseZ1, CancellationToken cancellationToken, Action<double> onResult)
{
NeedleZCalibrationExecutionContext executionContext = GetExecutionContext(1, autoRaiseZ1);
IReadOnlyList<double> results = await ExecuteCalibrationAsync(executionContext, null, cancellationToken, onResult);
if (results == null || results.Count == 0)
{
throw new InvalidOperationException("<22><><EFBFBD>ζԵ<CEB6>δ<EFBFBD><CEB4><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD><EFBFBD><EFBFBD>");
}
return results[0];
}
public async Task<IReadOnlyList<double>> ExecuteCalibrationAsync(NeedleZCalibrationExecutionContext executionContext, ActivityControl activityControl, CancellationToken cancellationToken, Action<double> onResult)
{
if (executionContext == null)
{
throw new ArgumentNullException(nameof(executionContext));
}
List<double> results = new List<double>();
for (int i = 0; i < executionContext.TouchCount; i++)
{
await CheckControlAsync(activityControl, cancellationToken);
double result = await ExecuteSingleCalibrationAsync(executionContext, activityControl, cancellationToken);
results.Add(result);
onResult?.Invoke(result);
}
if (executionContext.AutoRaiseZ1)
{
await CheckControlAsync(activityControl, cancellationToken);
_safeAxisMotion.MoveAbs(_hardwareManager.Axis_Z1, executionContext.Item.Z1StartPosition, cancellationToken);
}
return results;
}
private async Task<double> ExecuteSingleCalibrationAsync(NeedleZCalibrationExecutionContext executionContext, ActivityControl activityControl, CancellationToken cancellationToken)
{
bool foundSignal = false;
double start = executionContext.Item.Z1StartPosition;
double end = start - executionContext.Item.Z1DropMaxPosition;
await CheckControlAsync(activityControl, cancellationToken);
_safeAxisMotion.MoveAbs(_hardwareManager.Axis_Z1, start, cancellationToken);
while (Math.Abs(end - start) > Precision)
{
await CheckControlAsync(activityControl, cancellationToken);
double mid = (start + end) / 2.0;
if (mid < executionContext.SafeHeight)
{
throw new InvalidOperationException(string.Format("Ŀ<><C4BF>λ<EFBFBD><CEBB>[{0}]<5D><><EFBFBD><EFBFBD>Z1<5A>Ե<EFBFBD><D4B5><EFBFBD>ȫ<EFBFBD>߶<EFBFBD>[{1}]<5D><><EFBFBD>˶<EFBFBD><CBB6><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>", mid, executionContext.SafeHeight));
}
_safeAxisMotion.MoveAbs(_hardwareManager.Axis_Z1, mid, cancellationToken);
if (IsToolSetterTriggered())
{
end = mid;
foundSignal = true;
}
else
{
start = mid;
}
}
if (!foundSignal)
{
throw new InvalidOperationException("<22>ڷ<EFBFBD>Χ<EFBFBD><CEA7>δ<EFBFBD>ҵ<EFBFBD><D2B5>Ե<EFBFBD><D4B5>źţ<C5BA><C5A3>Ե<EFBFBD>ʧ<EFBFBD>ܡ<EFBFBD>\r\n<><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2>ź<EFBFBD>״̬<D7B4><CCAC>");
}
return _hardwareManager.Axis_Z1.State != null ? _hardwareManager.Axis_Z1.State.ActualPos : _hardwareManager.Axis_Z1.GetPositionImmediate();
}
private static async Task CheckControlAsync(ActivityControl activityControl, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
if (activityControl == null)
{
return;
}
activityControl.CancellationToken.ThrowIfCancellationRequested();
await activityControl.CheckPauseAsync();
cancellationToken.ThrowIfCancellationRequested();
activityControl.CancellationToken.ThrowIfCancellationRequested();
}
private bool IsToolSetterTriggered()
{
return _deviceIoMonitorService.IsPointOn(DeviceIoNames.Stage.ToolSetterSignal);
}
private static void ValidateCalibrationSetting(NeedleCalibrationSetting needleCalibrationSetting)
{
if (needleCalibrationSetting == null || needleCalibrationSetting.NeedleZCalibrationItem == null)
{
throw new InvalidOperationException(<><CEB4>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͷ<EFBFBD>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
}
}
private static void ValidateCalibrationItem(NeedleZCalibrationItem item)
{
if (item == null)
{
throw new ArgumentNullException(nameof(item));
}
if (item.Z1Speed <= 0)
{
throw new InvalidOperationException("Z1<5A>ٶȱ<D9B6><C8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>");
}
if (item.Z1DropMaxPosition <= 0)
{
throw new InvalidOperationException("Z1<5A>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>");
}
}
private static double ResolveSafeHeight(EquipmentParaSysSetting equipmentParaSysSetting)
{
if (equipmentParaSysSetting == null || equipmentParaSysSetting.SafeParaSysItem == null)
{
return 0;
}
return equipmentParaSysSetting.SafeParaSysItem.NeedleCalibSafeHeight;
}
}
public class NeedleZCalibrationExecutionContext
{
public NeedleZCalibrationExecutionContext(NeedleCalibrationSetting needleCalibrationSetting, NeedleZCalibrationItem item, int touchCount, bool autoRaiseZ1, double safeHeight)
{
NeedleCalibrationSetting = needleCalibrationSetting ?? throw new ArgumentNullException(nameof(needleCalibrationSetting));
Item = item ?? throw new ArgumentNullException(nameof(item));
TouchCount = touchCount;
AutoRaiseZ1 = autoRaiseZ1;
SafeHeight = safeHeight;
}
public NeedleCalibrationSetting NeedleCalibrationSetting { get; private set; }
public NeedleZCalibrationItem Item { get; private set; }
public int TouchCount { get; private set; }
public bool AutoRaiseZ1 { get; private set; }
public double SafeHeight { get; private set; }
}
}