添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
using MaxwellFramework.Core.Attributes;
|
||||
using MainShell.Alarm;
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Log;
|
||||
using MainShell.Motion.Safety;
|
||||
using MwFramework.Device;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Motion
|
||||
{
|
||||
[Singleton]
|
||||
public sealed class MotionAlarmReporter
|
||||
{
|
||||
private readonly AlarmOperate _alarmOperate;
|
||||
|
||||
public MotionAlarmReporter(AlarmOperate alarmOperate)
|
||||
{
|
||||
_alarmOperate = alarmOperate ?? throw new ArgumentNullException(nameof(alarmOperate));
|
||||
}
|
||||
|
||||
public async Task<bool> ReportAlarmAsync(int? alarmId)
|
||||
{
|
||||
if (!alarmId.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
await _alarmOperate.AlertAsync(alarmId.Value).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Singleton]
|
||||
public sealed class StagePlatformSafetyOptionsProvider
|
||||
{
|
||||
private const double DefaultMaxPlaneSpread = 5.0d;
|
||||
private const double DefaultMaxTravelPerStep = 10.0d;
|
||||
|
||||
public StagePlatformSafetyOptions GetOptions()
|
||||
{
|
||||
return new StagePlatformSafetyOptions(DefaultMaxPlaneSpread, DefaultMaxTravelPerStep);
|
||||
}
|
||||
}
|
||||
|
||||
[Singleton]
|
||||
public sealed class MotionPrecheckService
|
||||
{
|
||||
private readonly MotionAlarmReporter _motionAlarmReporter;
|
||||
private readonly IReadOnlyList<IMotionSafetyCheck> _motionSafetyChecks;
|
||||
|
||||
public MotionPrecheckService(HardwareManager hardware, MotionSafetyStateProvider motionSafetyStateProvider, MotionAlarmReporter motionAlarmReporter, StagePlatformSafetyOptionsProvider stagePlatformSafetyOptionsProvider)
|
||||
{
|
||||
if (hardware == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(hardware));
|
||||
}
|
||||
|
||||
if (motionSafetyStateProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(motionSafetyStateProvider));
|
||||
}
|
||||
|
||||
_motionAlarmReporter = motionAlarmReporter ?? throw new ArgumentNullException(nameof(motionAlarmReporter));
|
||||
var stagePlatformSafetyOptions = (stagePlatformSafetyOptionsProvider ?? throw new ArgumentNullException(nameof(stagePlatformSafetyOptionsProvider))).GetOptions();
|
||||
_motionSafetyChecks = new IMotionSafetyCheck[]
|
||||
{
|
||||
new MotionRequestDuplicateAxisCheck(),
|
||||
new MotionBatchSameSourceCheck(),
|
||||
new EmergencyStopReleasedCheck(motionSafetyStateProvider),
|
||||
new SafetyDoorClosedCheck(motionSafetyStateProvider),
|
||||
new AutoFlowModeCheck(motionSafetyStateProvider),
|
||||
new StageVacuumReadyCheck(motionSafetyStateProvider),
|
||||
new BondHeadSafePositionCheck(motionSafetyStateProvider),
|
||||
new StagePlatformPlaneMoveSafetyCheck(hardware, stagePlatformSafetyOptions)
|
||||
};
|
||||
}
|
||||
|
||||
public async Task ValidateAsync(MotionSafetyContext context, CancellationToken cancellationToken, int? fallbackAlarmId)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
if (context == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
foreach (var check in _motionSafetyChecks)
|
||||
{
|
||||
var result = check.Check(context);
|
||||
if (result == null || result.IsPassed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var failureMessage = string.Format("Motion precheck failed. Rule:{0} Kind:{1} Source:{2} Message:{3}", result.RuleName, context.RequestKind, context.Source ?? "N/A", result.Message);
|
||||
failureMessage.LogSysError();
|
||||
var alarmId = result.AlarmId ?? fallbackAlarmId;
|
||||
if (alarmId.HasValue)
|
||||
{
|
||||
await _motionAlarmReporter.ReportAlarmAsync(alarmId).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(failureMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Singleton]
|
||||
public sealed class MotionExecutionLogger
|
||||
{
|
||||
public void HandleMotionStarted(object sender, MotionStartedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
string.Format("Axis:{0} Motion:{1} Started StartPos:{2:F3} Target:{3}", e.AxisName, e.Operation, e.StartPosition, e.TargetPosition.HasValue ? e.TargetPosition.Value.ToString("F3") : "N/A").LogInfo();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string.Format("Axis:{0} motion start log failed. Error:{1}", e.AxisName, ex.Message).LogSysError();
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleMotionFinished(object sender, MotionFinishedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = e.Result;
|
||||
var message = string.Format("Axis:{0} Motion:{1} Finished Success:{2} Cancelled:{3} EndPos:{4:F3} Duration:{5}ms FailureStage:{6}", result.AxisName, result.Operation, result.Succeeded, result.Cancelled, result.EndPosition, result.DurationMilliseconds, result.FailureStage ?? "N/A");
|
||||
if (result.Succeeded)
|
||||
{
|
||||
message.LogInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
var error = string.Format("{0} Error:{1}", message, result.Exception);
|
||||
error.LogSysError();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string.Format("Axis:{0} motion finish log failed. Error:{1}", e.AxisName, ex.Message).LogSysError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Singleton]
|
||||
public sealed class MotionControllerRegistry
|
||||
{
|
||||
private readonly Dictionary<string, ControllerEntry> _controllers = new Dictionary<string, ControllerEntry>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly object _syncRoot = new object();
|
||||
private readonly MotionExecutionLogger _motionExecutionLogger;
|
||||
|
||||
private sealed class ControllerEntry
|
||||
{
|
||||
public ControllerEntry(IAxis axis, MotionController controller)
|
||||
{
|
||||
Axis = axis ?? throw new ArgumentNullException(nameof(axis));
|
||||
Controller = controller ?? throw new ArgumentNullException(nameof(controller));
|
||||
}
|
||||
|
||||
public IAxis Axis { get; }
|
||||
public MotionController Controller { get; }
|
||||
}
|
||||
|
||||
public MotionControllerRegistry(MotionExecutionLogger motionExecutionLogger)
|
||||
{
|
||||
_motionExecutionLogger = motionExecutionLogger ?? throw new ArgumentNullException(nameof(motionExecutionLogger));
|
||||
}
|
||||
|
||||
public MotionController GetController(IAxis axis)
|
||||
{
|
||||
if (axis == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(axis));
|
||||
}
|
||||
|
||||
var axisName = axis.Name;
|
||||
if (string.IsNullOrWhiteSpace(axisName))
|
||||
{
|
||||
return CreateController(axis);
|
||||
}
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
ControllerEntry entry;
|
||||
if (_controllers.TryGetValue(axisName, out entry) && ReferenceEquals(entry.Axis, axis))
|
||||
{
|
||||
return entry.Controller;
|
||||
}
|
||||
|
||||
var controller = CreateController(axis);
|
||||
_controllers[axisName] = new ControllerEntry(axis, controller);
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
|
||||
private MotionController CreateController(IAxis axis)
|
||||
{
|
||||
var controller = new MotionController(axis);
|
||||
controller.MotionStarted += _motionExecutionLogger.HandleMotionStarted;
|
||||
controller.MotionFinished += _motionExecutionLogger.HandleMotionFinished;
|
||||
return controller;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user