添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Log;
|
||||
using MainShell.Motion;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.PageCalib.OriginCalib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// ʾ<><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڱ궨<DAB1><EAB6A8><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public class VisionCapturePostProcessor : ICalibrationPostProcessor
|
||||
{
|
||||
public string Name => "VisionCapture";
|
||||
|
||||
public async Task ExecuteAsync(OriginCalibrationExecutionResult calibrationResult, CancellationToken cancellationToken,object pars= null)
|
||||
{
|
||||
"ִ<><D6B4><EFBFBD><EFBFBD><EFBFBD>պ<EFBFBD><D5BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...".LogInfo();
|
||||
|
||||
// <20>ڴ˴<DAB4><CBB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><><EFBFBD>磺await _visionService.CaptureAsync(cancellationToken);
|
||||
|
||||
await Task.Delay(100, cancellationToken);
|
||||
|
||||
"<22><><EFBFBD>պ<EFBFBD><D5BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>".LogInfo();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <20>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڱ궨<DAB1><EAB6A8><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD>λ<EFBFBD><CEBB>ִ<EFBFBD>бƽ<D0B1><C6BD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public class ApproachAlignmentPostProcessor : ICalibrationPostProcessor
|
||||
{
|
||||
private readonly ApproachAlignmentService _approachAlignmentService;
|
||||
private readonly IReadOnlyList<ApproachAlignmentAxis> _alignmentAxes;
|
||||
private readonly CameraType _camera;
|
||||
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD>캯<EFBFBD><ECBAAF>
|
||||
/// </summary>
|
||||
/// <param name="approachAlignmentService"><3E>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||
/// <param name="alignmentAxes"><3E><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD></param>
|
||||
/// <param name="camera"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>Ĭ<EFBFBD><C4AC>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
|
||||
public ApproachAlignmentPostProcessor(
|
||||
ApproachAlignmentService approachAlignmentService,
|
||||
IEnumerable<ApproachAlignmentAxis> alignmentAxes,
|
||||
CameraType camera = CameraType.TopPositionCamera)
|
||||
{
|
||||
_approachAlignmentService = approachAlignmentService ?? throw new ArgumentNullException(nameof(approachAlignmentService));
|
||||
|
||||
if (alignmentAxes == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(alignmentAxes));
|
||||
}
|
||||
|
||||
_alignmentAxes = alignmentAxes.ToList().AsReadOnly();
|
||||
|
||||
if (_alignmentAxes.Count == 0)
|
||||
{
|
||||
throw new ArgumentException("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫһ<D2AA><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ᡣ", nameof(alignmentAxes));
|
||||
}
|
||||
|
||||
_camera = camera;
|
||||
}
|
||||
|
||||
public string Name => "ApproachAlignment";
|
||||
|
||||
public async Task ExecuteAsync(OriginCalibrationExecutionResult calibrationResult, CancellationToken cancellationToken,object pars= null)
|
||||
{
|
||||
"ִ<>бƽ<D0B1><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...".LogInfo();
|
||||
|
||||
try
|
||||
{
|
||||
ApproachAlignmentRequest alignmentRequest = new ApproachAlignmentRequest(_alignmentAxes, _camera);
|
||||
if(pars is CenterRecognitionParameters centerRecognitionParameters)
|
||||
{
|
||||
alignmentRequest.RecognitionParameters = centerRecognitionParameters;
|
||||
}
|
||||
|
||||
ApproachAlignmentResult alignmentResult = await _approachAlignmentService.ApproachAlignmentAsync(
|
||||
alignmentRequest,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (alignmentResult.Succeeded)
|
||||
{
|
||||
string.Format("<22>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><C9A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>{0}", alignmentResult.CompletedIterations).LogInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
string.Format("<22>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>{0}", alignmentResult.Message).LogInfo();
|
||||
throw alignmentResult.Exception ?? new InvalidOperationException(alignmentResult.Message);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
"<22>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>".LogInfo();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string.Format("<22>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3>{0}", ex.Message).LogInfo();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD>ζ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڱ궨<DAB1><EAB6A8><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD>λ<EFBFBD><CEBB>ִ<EFBFBD><D6B4>һ<EFBFBD><D2BB>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD>˶<EFBFBD>
|
||||
/// </summary>
|
||||
public class SingleAlignmentPostProcessor : ICalibrationPostProcessor
|
||||
{
|
||||
private readonly ApproachAlignmentService _approachAlignmentService;
|
||||
private readonly IReadOnlyList<ApproachAlignmentAxis> _alignmentAxes;
|
||||
private readonly CameraType _camera;
|
||||
|
||||
public SingleAlignmentPostProcessor(
|
||||
ApproachAlignmentService approachAlignmentService,
|
||||
IEnumerable<ApproachAlignmentAxis> alignmentAxes,
|
||||
CameraType camera = CameraType.TopPositionCamera)
|
||||
{
|
||||
_approachAlignmentService = approachAlignmentService ?? throw new ArgumentNullException(nameof(approachAlignmentService));
|
||||
|
||||
if (alignmentAxes == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(alignmentAxes));
|
||||
}
|
||||
|
||||
_alignmentAxes = alignmentAxes.ToList().AsReadOnly();
|
||||
|
||||
if (_alignmentAxes.Count == 0)
|
||||
{
|
||||
throw new ArgumentException("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫһ<D2AA><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ᡣ", nameof(alignmentAxes));
|
||||
}
|
||||
|
||||
_camera = camera;
|
||||
}
|
||||
|
||||
public string Name => "SingleAlignment";
|
||||
|
||||
public async Task ExecuteAsync(OriginCalibrationExecutionResult calibrationResult, CancellationToken cancellationToken, object pars = null)
|
||||
{
|
||||
"ִ<>е<EFBFBD><D0B5>ζ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...".LogInfo();
|
||||
|
||||
try
|
||||
{
|
||||
ApproachAlignmentRequest alignmentRequest = new ApproachAlignmentRequest(_alignmentAxes, _camera);
|
||||
if (pars is CenterRecognitionParameters centerRecognitionParameters)
|
||||
{
|
||||
alignmentRequest.RecognitionParameters = centerRecognitionParameters;
|
||||
}
|
||||
|
||||
ApproachAlignmentResult alignmentResult = await _approachAlignmentService.SingleAlignmentAsync(
|
||||
alignmentRequest,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (alignmentResult.Succeeded)
|
||||
{
|
||||
string.Format("<22><><EFBFBD>ζ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD>ɣ<EFBFBD>ִ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>{0}", alignmentResult.CompletedIterations).LogInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
string.Format("<22><><EFBFBD>ζ<EFBFBD>λʧ<CEBB>ܣ<EFBFBD>{0}", alignmentResult.Message).LogInfo();
|
||||
throw alignmentResult.Exception ?? new InvalidOperationException(alignmentResult.Message);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
"<22><><EFBFBD>ζ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>".LogInfo();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string.Format("<22><><EFBFBD>ζ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3>{0}", ex.Message).LogInfo();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.PageCalib.OriginCalib.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// 标定后处理接口,用于在避让轴和标定轴移动到位后执行模块特定的逻辑
|
||||
/// </summary>
|
||||
public interface ICalibrationPostProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// 处理器名称,用于日志和诊断
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 在运动完成后、标定前执行处理逻辑
|
||||
/// </summary>
|
||||
/// <param name="calibrationResult">运动执行结果,包含各轴的实际位置</param>
|
||||
/// <param name="cancellationToken">取消令牌</param>
|
||||
/// <param name="pars">可选参数</param>
|
||||
/// <returns>异步任务</returns>
|
||||
Task ExecuteAsync(OriginCalibrationExecutionResult calibrationResult, CancellationToken cancellationToken,object pars=null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
using MainShell.Hardware;
|
||||
using MainShell.Log;
|
||||
using MainShell.Motion;
|
||||
using MainShell.PageCalib.OriginCalib.Model;
|
||||
using MaxwellFramework.Core.Attributes;
|
||||
using MwFramework.Device;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.PageCalib.OriginCalib.Service
|
||||
{
|
||||
public sealed class OriginCalibrationExecutionResult
|
||||
{
|
||||
public OriginCalibrationExecutionResult(IDictionary<string, double> actualPositions)
|
||||
{
|
||||
var positions = actualPositions ?? new Dictionary<string, double>(StringComparer.Ordinal);
|
||||
ActualPositions = new ReadOnlyDictionary<string, double>(new Dictionary<string, double>(positions, StringComparer.Ordinal));
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<string, double> ActualPositions { get; private set; }
|
||||
}
|
||||
|
||||
[Singleton]
|
||||
public class OriginCalibrationMotionService
|
||||
{
|
||||
private const int PositionSettleDelayMilliseconds = 200;
|
||||
|
||||
private readonly HardwareManager _hardware;
|
||||
private readonly SafeAxisMotion _safeAxisMotion;
|
||||
|
||||
public OriginCalibrationMotionService(HardwareManager hardware, SafeAxisMotion safeAxisMotion)
|
||||
{
|
||||
_hardware = hardware ?? throw new ArgumentNullException(nameof(hardware));
|
||||
_safeAxisMotion = safeAxisMotion ?? throw new ArgumentNullException(nameof(safeAxisMotion));
|
||||
}
|
||||
|
||||
public async Task MoveAxisAsync(string axisName, double position, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
string.Format("原点标定正在移动轴“{0}”到位置 {1:F3}。", axisName, position).LogInfo();
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _safeAxisMotion.MoveAbsAsync(axisName, position, MotionController.DefaultTimeoutMilliseconds, cancellationToken).ConfigureAwait(false);
|
||||
result.EnsureSuccess();
|
||||
string.Format("原点标定轴“{0}”已到达目标位置 {1:F3}。", axisName, position).LogInfo();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
string.Format("原点标定轴“{0}”移动已取消。", axisName).LogInfo();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string.Format("原点标定轴“{0}”移动失败:{1}", axisName, ex.Message).LogSysError();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<OriginCalibrationExecutionResult> ExecuteAsync(IEnumerable<AvoidanceAxisItem> avoidanceAxes, IEnumerable<CalibrationAxisItem> calibrationAxes, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
var avoidanceAxisList = avoidanceAxes == null ? new List<AvoidanceAxisItem>() : avoidanceAxes.Where(item => item != null).ToList();
|
||||
var calibrationAxisList = calibrationAxes == null ? new List<CalibrationAxisItem>() : calibrationAxes.Where(item => item != null).ToList();
|
||||
|
||||
string.Format(
|
||||
"原点标定执行开始,避让轴数量:{0},标定轴数量:{1}。",
|
||||
avoidanceAxisList.Count,
|
||||
calibrationAxisList.Count).LogInfo();
|
||||
|
||||
try
|
||||
{
|
||||
await ExecuteBatchAsync(CreateRequests(avoidanceAxisList, item => item.AxisName, item => item.Position), cancellationToken).ConfigureAwait(false);
|
||||
await ExecuteBatchAsync(CreateRequests(calibrationAxisList, item => item.AxisName, item => item.TargetPosition), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
string.Format(
|
||||
"原点标定等待 {0} ms 以稳定轴反馈,再读取实际位置。",
|
||||
PositionSettleDelayMilliseconds).LogInfo();
|
||||
await Task.Delay(PositionSettleDelayMilliseconds, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var actualPositions = new Dictionary<string, double>(StringComparer.Ordinal);
|
||||
foreach (var calibrationAxis in calibrationAxisList)
|
||||
{
|
||||
if (calibrationAxis == null || string.IsNullOrWhiteSpace(calibrationAxis.AxisName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var axis = _hardware.GetAxisByName(calibrationAxis.AxisName);
|
||||
if (axis == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
actualPositions[calibrationAxis.AxisName] = Math.Round(GetActualPosition(axis), 3);
|
||||
string.Format(
|
||||
"原点标定已采集轴“{0}”的实际位置:{1:F3}。",
|
||||
calibrationAxis.AxisName,
|
||||
actualPositions[calibrationAxis.AxisName]).LogInfo();
|
||||
}
|
||||
|
||||
string.Format("原点标定执行完成,共采集 {0} 个标定轴的实际位置。", actualPositions.Count).LogInfo();
|
||||
return new OriginCalibrationExecutionResult(actualPositions);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
"原点标定执行已取消。".LogInfo();
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string.Format("原点标定执行失败:{0}", ex.Message).LogSysError();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ExecuteBatchAsync(MotionMoveRequest[] requests, CancellationToken cancellationToken)
|
||||
{
|
||||
if (requests.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var result = await _safeAxisMotion.SafeMoveAsync(cancellationToken, requests).ConfigureAwait(false);
|
||||
result.EnsureSuccess();
|
||||
}
|
||||
|
||||
private MotionMoveRequest[] CreateRequests<TItem>(IEnumerable<TItem> items, Func<TItem, string> axisNameAccessor, Func<TItem, double> positionAccessor)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
return new MotionMoveRequest[0];
|
||||
}
|
||||
|
||||
var requests = new List<MotionMoveRequest>();
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var axisName = axisNameAccessor(item);
|
||||
if (string.IsNullOrWhiteSpace(axisName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_hardware.GetAxisByName(axisName) == null)
|
||||
{
|
||||
string.Format("原点标定轴“{0}”在硬件管理器中不存在。", axisName).LogSysError();
|
||||
continue;
|
||||
}
|
||||
|
||||
requests.Add(MotionMoveRequest.ForAxisName(axisName, positionAccessor(item)));
|
||||
}
|
||||
|
||||
return requests.ToArray();
|
||||
}
|
||||
|
||||
private static double GetActualPosition(IAxis axis)
|
||||
{
|
||||
return axis.State != null ? axis.State.ActualPos : axis.GetPositionImmediate();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user