using MainShell.EventArgsFolder; using MainShell.Log; using MainShell.Motion; using MaxwellFramework.Core.Attributes; using MwFramework.Device; using MwFramework.Device.Delta; using Stylet; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace MainShell.Hardware { [Singleton] public sealed class AxisHomeService : IHandle { private readonly HardwareManager _hardwareManager; private readonly SafeAxisMotion _safeAxisMotion; private readonly IDeltaAxisExtend _deltaAxisExtend; private readonly Dictionary _latestOriginCalibOffsets = new Dictionary(StringComparer.Ordinal); public IReadOnlyDictionary LatestOriginCalibOffsets { get { return _latestOriginCalibOffsets; } } public AxisHomeService(HardwareManager hardwareManager, SafeAxisMotion safeAxisMotion, IEventAggregator eventAggregator) { _hardwareManager = hardwareManager ?? throw new ArgumentNullException(nameof(hardwareManager)); _safeAxisMotion = safeAxisMotion ?? throw new ArgumentNullException(nameof(safeAxisMotion)); if (eventAggregator == null) { throw new ArgumentNullException(nameof(eventAggregator)); } eventAggregator.Subscribe(this); _deltaAxisExtend=_hardwareManager.TdCard as IDeltaAxisExtend; SetHomeDoneEvent(AxisName.Axis_PHS_Z1); SetHomeDoneEvent(AxisName.Axis_PHS_Z3); SetHomeDoneEvent(AxisName.Axis_PHS_Z4); SetHomeDoneEvent(AxisName.Axis_PHS_Z5); SetHomeDoneEvent(AxisName.Axis_PHS_Z6); } private void SetHomeDoneEvent(string axisName) { var axis = ResolveAxis(axisName); if (axis != null && axis is IDeltaAxisEvent deltaAxis) { deltaAxis.HomeFinished -= DeltaAxis_HomeFinished; deltaAxis.HomeFinished += DeltaAxis_HomeFinished; } } private void DeltaAxis_HomeFinished(IAxis arg1, bool arg2) { if(arg2) { } } private void SetHomeOffset(IAxis axis, double offset) { if (_deltaAxisExtend != null) { _deltaAxisExtend.SetAxisCurrentPosition(axis, offset); } } public void Home(string axisName) { Home(axisName, CancellationToken.None); } public void Home(string axisName, CancellationToken cancellationToken) { HomeAsync(axisName, MotionController.DefaultTimeoutMilliseconds, cancellationToken).GetAwaiter().GetResult().EnsureSuccess(); } public void Home(IAxis axis) { Home(axis, CancellationToken.None); } public void Home(IAxis axis, CancellationToken cancellationToken) { HomeAsync(axis, MotionController.DefaultTimeoutMilliseconds, cancellationToken).GetAwaiter().GetResult().EnsureSuccess(); } public void Home(params string[] axisNames) { Home(CancellationToken.None, axisNames); } public void Home(CancellationToken cancellationToken, params string[] axisNames) { HomeAsync(MotionController.DefaultTimeoutMilliseconds, cancellationToken, axisNames).GetAwaiter().GetResult().EnsureSuccess(); } public async Task HomeAsync(string axisName, int timeoutMilliseconds = MotionController.DefaultTimeoutMilliseconds, CancellationToken cancellationToken = default(CancellationToken), int? alarmId = null) { if (string.IsNullOrWhiteSpace(axisName)) { throw new ArgumentNullException(nameof(axisName)); } IAxis axis = ResolveAxis(axisName); return await HomeAsync(axis, timeoutMilliseconds, cancellationToken, alarmId).ConfigureAwait(false); } public async Task HomeAsync(IAxis axis, int timeoutMilliseconds = MotionController.DefaultTimeoutMilliseconds, CancellationToken cancellationToken = default(CancellationToken), int? alarmId = null) { IAxis resolvedAxis = axis ?? throw new ArgumentNullException(nameof(axis)); string axisName = resolvedAxis.Name ?? string.Empty; DateTime startedAt = DateTime.Now; string.Format("Axis home started. Axis:{0}", axisName).LogInfo(); try { MotionResult result = await _safeAxisMotion.HomeAsync(resolvedAxis, timeoutMilliseconds, cancellationToken, alarmId).ConfigureAwait(false); if (result.Succeeded) { string.Format("Axis home completed. Axis:{0} Duration:{1}ms", axisName, (DateTime.Now - startedAt).TotalMilliseconds.ToString("F0")).LogInfo(); } else if (result.Cancelled) { string.Format("Axis home cancelled. Axis:{0}", axisName).LogInfo(); } else { string failureMessage = string.IsNullOrWhiteSpace(result.Message) ? "Unknown axis home failure." : result.Message; string.Format("Axis home failed. Axis:{0} Error:{1}", axisName, failureMessage).LogSysError(); } return result; } catch (Exception ex) { string.Format("Axis home exception. Axis:{0} Error:{1}", axisName, ex.Message).LogSysError(); throw; } } public Task HomeAsync(params string[] axisNames) { return HomeAsync(MotionController.DefaultTimeoutMilliseconds, CancellationToken.None, axisNames); } public Task HomeAsync(CancellationToken cancellationToken, params string[] axisNames) { return HomeAsync(MotionController.DefaultTimeoutMilliseconds, cancellationToken, axisNames); } public async Task HomeAsync(int timeoutMilliseconds, CancellationToken cancellationToken, params string[] axisNames) { string[] normalizedAxisNames = NormalizeAxisNames(axisNames); if (normalizedAxisNames.Length == 0) { return new MotionBatchResult(Array.Empty()); } IAxis[] axes = normalizedAxisNames.Select(ResolveAxis).ToArray(); return await HomeAsync(timeoutMilliseconds, cancellationToken, axes).ConfigureAwait(false); } public Task HomeAsync(params IAxis[] axes) { return HomeAsync(MotionController.DefaultTimeoutMilliseconds, CancellationToken.None, axes); } public Task HomeAsync(CancellationToken cancellationToken, params IAxis[] axes) { return HomeAsync(MotionController.DefaultTimeoutMilliseconds, cancellationToken, axes); } public async Task HomeAsync(int timeoutMilliseconds, CancellationToken cancellationToken, params IAxis[] axes) { IAxis[] normalizedAxes = NormalizeAxes(axes); if (normalizedAxes.Length == 0) { return new MotionBatchResult(Array.Empty()); } List results = new List(normalizedAxes.Length); foreach (IAxis axis in normalizedAxes) { MotionResult result = await HomeAsync(axis, timeoutMilliseconds, cancellationToken).ConfigureAwait(false); results.Add(result); } return new MotionBatchResult(results); } public Task SafeHomeAsync(params string[] axisNames) { return SafeHomeAsync(CancellationToken.None, axisNames); } public async Task SafeHomeAsync(CancellationToken cancellationToken, params string[] axisNames) { string[] normalizedAxisNames = NormalizeAxisNames(axisNames); if (normalizedAxisNames.Length == 0) { return new MotionBatchResult(Array.Empty()); } string.Format("Batch axis home started. Axes:{0}", string.Join(", ", normalizedAxisNames)).LogInfo(); try { MotionBatchResult result = await _safeAxisMotion.SafeHomeAsync(cancellationToken, normalizedAxisNames).ConfigureAwait(false); if (result.Succeeded) { string.Format("Batch axis home completed. Axes:{0}", string.Join(", ", normalizedAxisNames)).LogInfo(); } else { IEnumerable failedAxes = result.Results.Where(x => x != null && !x.Succeeded).Select(x => x.AxisName ?? string.Empty); string.Format("Batch axis home failed. Axes:{0}", string.Join(", ", failedAxes)).LogSysError(); } return result; } catch (Exception ex) { string.Format("Batch axis home exception. Axes:{0} Error:{1}", string.Join(", ", normalizedAxisNames), ex.Message).LogSysError(); throw; } } public IAxis GetAxis(string axisName) { return ResolveAxis(axisName); } public bool TryGetOriginCalibOffset(string axisName, out double offset) { offset = 0; if (string.IsNullOrWhiteSpace(axisName)) { return false; } return _latestOriginCalibOffsets.TryGetValue(axisName, out offset); } private IAxis ResolveAxis(string axisName) { IAxis axis = _hardwareManager.GetAxisByName(axisName); if (axis == null) { throw new ArgumentException(string.Format("Axis with name {0} was not found.", axisName), nameof(axisName)); } return axis; } private static string[] NormalizeAxisNames(IEnumerable axisNames) { return (axisNames ?? Enumerable.Empty()) .Where(x => !string.IsNullOrWhiteSpace(x)) .Distinct(StringComparer.Ordinal) .ToArray(); } private static IAxis[] NormalizeAxes(IEnumerable axes) { return (axes ?? Enumerable.Empty()) .Where(x => x != null) .GroupBy(x => x.Name ?? string.Empty, StringComparer.Ordinal) .Select(x => x.First()) .ToArray(); } public void Handle(OriginCalibDataChangedEventArgs eventArgs) { if (eventArgs == null) { return; } _latestOriginCalibOffsets.Clear(); if (eventArgs.Axes != null) { foreach (OriginCalibAxisOffsetChangedItem axis in eventArgs.Axes) { if (axis == null || string.IsNullOrWhiteSpace(axis.AxisName)) { continue; } _latestOriginCalibOffsets[axis.AxisName] = axis.Offset; } } string.Format( "Origin calibration data changed received. AxisCount:{0}", _latestOriginCalibOffsets.Count).LogInfo(); } } }