534 lines
21 KiB
C#
534 lines
21 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Prism.Events;
|
|
using XP.Hardware.Detector.Abstractions.Enums;
|
|
using XP.Hardware.Detector.Abstractions.Events;
|
|
|
|
namespace XP.Hardware.Detector.Abstractions
|
|
{
|
|
/// <summary>
|
|
/// 面阵探测器抽象基类 | Area detector abstract base class
|
|
/// 封装通用逻辑:参数校验、状态更新、事件发布
|
|
/// 使用模板方法模式,子类实现具体的硬件操作
|
|
/// </summary>
|
|
public abstract class AreaDetectorBase : IAreaDetector
|
|
{
|
|
protected readonly IEventAggregator _eventAggregator;
|
|
protected readonly object _statusLock = new object();
|
|
protected DetectorStatus _status = DetectorStatus.Uninitialized;
|
|
protected bool _disposed = false;
|
|
|
|
/// <summary>
|
|
/// 探测器状态 | Detector status
|
|
/// </summary>
|
|
public DetectorStatus Status
|
|
{
|
|
get
|
|
{
|
|
lock (_statusLock)
|
|
{
|
|
return _status;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 探测器类型 | Detector type
|
|
/// </summary>
|
|
public abstract DetectorType Type { get; }
|
|
|
|
/// <summary>
|
|
/// 构造函数 | Constructor
|
|
/// </summary>
|
|
/// <param name="eventAggregator">事件聚合器 | Event aggregator</param>
|
|
protected AreaDetectorBase(IEventAggregator eventAggregator)
|
|
{
|
|
_eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化探测器 | Initialize detector
|
|
/// </summary>
|
|
public async Task<DetectorResult> InitializeAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
// 参数校验 | Parameter validation
|
|
if (Status != DetectorStatus.Uninitialized)
|
|
{
|
|
return DetectorResult.Failure("探测器已初始化 | Detector already initialized");
|
|
}
|
|
|
|
try
|
|
{
|
|
// 更新状态 | Update status
|
|
UpdateStatus(DetectorStatus.Initializing);
|
|
|
|
// 调用子类实现 | Call derived class implementation
|
|
var result = await InitializeInternalAsync(cancellationToken);
|
|
|
|
if (result.IsSuccess)
|
|
{
|
|
UpdateStatus(DetectorStatus.Ready);
|
|
}
|
|
else
|
|
{
|
|
UpdateStatus(DetectorStatus.Error);
|
|
PublishError(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
UpdateStatus(DetectorStatus.Error);
|
|
var errorResult = DetectorResult.Failure($"初始化异常 | Initialization exception: {ex.Message}", ex);
|
|
PublishError(errorResult);
|
|
return errorResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 启动连续采集 | Start continuous acquisition
|
|
/// </summary>
|
|
public async Task<DetectorResult> StartAcquisitionAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
// 参数校验 | Parameter validation
|
|
if (Status != DetectorStatus.Ready)
|
|
{
|
|
return DetectorResult.Failure($"探测器状态不正确,当前状态:{Status} | Detector status incorrect, current status: {Status}");
|
|
}
|
|
|
|
try
|
|
{
|
|
// 更新状态 | Update status
|
|
UpdateStatus(DetectorStatus.Acquiring);
|
|
|
|
// 调用子类实现 | Call derived class implementation
|
|
var result = await StartAcquisitionInternalAsync(cancellationToken);
|
|
|
|
if (!result.IsSuccess)
|
|
{
|
|
UpdateStatus(DetectorStatus.Ready);
|
|
PublishError(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
UpdateStatus(DetectorStatus.Error);
|
|
var errorResult = DetectorResult.Failure($"启动采集异常 | Start acquisition exception: {ex.Message}", ex);
|
|
PublishError(errorResult);
|
|
return errorResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 停止采集 | Stop acquisition
|
|
/// </summary>
|
|
public async Task<DetectorResult> StopAcquisitionAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
// 参数校验 | Parameter validation
|
|
// 未初始化时不允许停止采集操作 | Stop acquisition not allowed when uninitialized
|
|
if (Status == DetectorStatus.Uninitialized)
|
|
{
|
|
return DetectorResult.Failure("探测器未初始化,无法执行停止采集操作 | Detector not initialized, cannot stop acquisition");
|
|
}
|
|
|
|
try
|
|
{
|
|
// 调用子类实现 | Call derived class implementation
|
|
var result = await StopAcquisitionInternalAsync(cancellationToken);
|
|
|
|
if (result.IsSuccess)
|
|
{
|
|
UpdateStatus(DetectorStatus.Ready);
|
|
}
|
|
else
|
|
{
|
|
PublishError(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
UpdateStatus(DetectorStatus.Error);
|
|
var errorResult = DetectorResult.Failure($"停止采集异常 | Stop acquisition exception: {ex.Message}", ex);
|
|
PublishError(errorResult);
|
|
return errorResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 单帧采集 | Single frame acquisition
|
|
/// </summary>
|
|
public async Task<DetectorResult> AcquireSingleFrameAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
// 参数校验 | Parameter validation
|
|
if (Status != DetectorStatus.Ready)
|
|
{
|
|
return DetectorResult.Failure($"探测器状态不正确,当前状态:{Status} | Detector status incorrect, current status: {Status}");
|
|
}
|
|
|
|
try
|
|
{
|
|
// 更新状态 | Update status
|
|
UpdateStatus(DetectorStatus.Acquiring);
|
|
|
|
// 调用子类实现 | Call derived class implementation
|
|
var result = await AcquireSingleFrameInternalAsync(cancellationToken);
|
|
|
|
// 恢复状态 | Restore status
|
|
UpdateStatus(DetectorStatus.Ready);
|
|
|
|
if (!result.IsSuccess)
|
|
{
|
|
PublishError(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
UpdateStatus(DetectorStatus.Error);
|
|
var errorResult = DetectorResult.Failure($"单帧采集异常 | Single frame acquisition exception: {ex.Message}", ex);
|
|
PublishError(errorResult);
|
|
return errorResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 暗场校正 | Dark field correction
|
|
/// </summary>
|
|
public async Task<DetectorResult> DarkCorrectionAsync(int frameCount, CancellationToken cancellationToken = default)
|
|
{
|
|
// 参数校验 | Parameter validation
|
|
if (Status != DetectorStatus.Ready)
|
|
{
|
|
return DetectorResult.Failure($"探测器状态不正确,当前状态:{Status} | Detector status incorrect, current status: {Status}");
|
|
}
|
|
|
|
if (frameCount <= 0)
|
|
{
|
|
return DetectorResult.Failure("帧数必须大于 0 | Frame count must be greater than 0");
|
|
}
|
|
|
|
try
|
|
{
|
|
// 更新状态 | Update status
|
|
UpdateStatus(DetectorStatus.Correcting);
|
|
|
|
// 调用子类实现 | Call derived class implementation
|
|
var result = await DarkCorrectionInternalAsync(frameCount, cancellationToken);
|
|
|
|
// 恢复状态 | Restore status
|
|
UpdateStatus(DetectorStatus.Ready);
|
|
|
|
if (result.IsSuccess)
|
|
{
|
|
PublishCorrectionCompleted(CorrectionType.Dark, result);
|
|
}
|
|
else
|
|
{
|
|
PublishError(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
UpdateStatus(DetectorStatus.Error);
|
|
var errorResult = DetectorResult.Failure($"暗场校正异常 | Dark correction exception: {ex.Message}", ex);
|
|
PublishError(errorResult);
|
|
return errorResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 增益校正 | Gain correction
|
|
/// </summary>
|
|
public async Task<DetectorResult> GainCorrectionAsync(int frameCount, CancellationToken cancellationToken = default)
|
|
{
|
|
// 参数校验 | Parameter validation
|
|
if (Status != DetectorStatus.Ready)
|
|
{
|
|
return DetectorResult.Failure($"探测器状态不正确,当前状态:{Status} | Detector status incorrect, current status: {Status}");
|
|
}
|
|
|
|
if (frameCount <= 0)
|
|
{
|
|
return DetectorResult.Failure("帧数必须大于 0 | Frame count must be greater than 0");
|
|
}
|
|
|
|
try
|
|
{
|
|
// 更新状态 | Update status
|
|
UpdateStatus(DetectorStatus.Correcting);
|
|
|
|
// 调用子类实现 | Call derived class implementation
|
|
var result = await GainCorrectionInternalAsync(frameCount, cancellationToken);
|
|
|
|
// 恢复状态 | Restore status
|
|
UpdateStatus(DetectorStatus.Ready);
|
|
|
|
if (result.IsSuccess)
|
|
{
|
|
PublishCorrectionCompleted(CorrectionType.Gain, result);
|
|
}
|
|
else
|
|
{
|
|
PublishError(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
UpdateStatus(DetectorStatus.Error);
|
|
var errorResult = DetectorResult.Failure($"增益校正异常 | Gain correction exception: {ex.Message}", ex);
|
|
PublishError(errorResult);
|
|
return errorResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自动校正 | Auto correction
|
|
/// </summary>
|
|
public async Task<DetectorResult> AutoCorrectionAsync(int frameCount, CancellationToken cancellationToken = default)
|
|
{
|
|
// 参数校验 | Parameter validation
|
|
if (Status != DetectorStatus.Ready)
|
|
{
|
|
return DetectorResult.Failure($"探测器状态不正确,当前状态:{Status} | Detector status incorrect, current status: {Status}");
|
|
}
|
|
|
|
if (frameCount <= 0)
|
|
{
|
|
return DetectorResult.Failure("帧数必须大于 0 | Frame count must be greater than 0");
|
|
}
|
|
|
|
try
|
|
{
|
|
// 更新状态 | Update status
|
|
UpdateStatus(DetectorStatus.Correcting);
|
|
|
|
// 调用子类实现 | Call derived class implementation
|
|
var result = await AutoCorrectionInternalAsync(frameCount, cancellationToken);
|
|
|
|
// 恢复状态 | Restore status
|
|
UpdateStatus(DetectorStatus.Ready);
|
|
|
|
if (result.IsSuccess)
|
|
{
|
|
PublishCorrectionCompleted(CorrectionType.Auto, result);
|
|
}
|
|
else
|
|
{
|
|
PublishError(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
UpdateStatus(DetectorStatus.Error);
|
|
var errorResult = DetectorResult.Failure($"自动校正异常 | Auto correction exception: {ex.Message}", ex);
|
|
PublishError(errorResult);
|
|
return errorResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 坏像素校正 | Bad pixel correction
|
|
/// </summary>
|
|
public async Task<DetectorResult> BadPixelCorrectionAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
// 参数校验 | Parameter validation
|
|
if (Status != DetectorStatus.Ready)
|
|
{
|
|
return DetectorResult.Failure($"探测器状态不正确,当前状态:{Status} | Detector status incorrect, current status: {Status}");
|
|
}
|
|
|
|
try
|
|
{
|
|
// 更新状态 | Update status
|
|
UpdateStatus(DetectorStatus.Correcting);
|
|
|
|
// 调用子类实现 | Call derived class implementation
|
|
var result = await BadPixelCorrectionInternalAsync(cancellationToken);
|
|
|
|
// 恢复状态 | Restore status
|
|
UpdateStatus(DetectorStatus.Ready);
|
|
|
|
if (result.IsSuccess)
|
|
{
|
|
PublishCorrectionCompleted(CorrectionType.BadPixel, result);
|
|
}
|
|
else
|
|
{
|
|
PublishError(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
UpdateStatus(DetectorStatus.Error);
|
|
var errorResult = DetectorResult.Failure($"坏像素校正异常 | Bad pixel correction exception: {ex.Message}", ex);
|
|
PublishError(errorResult);
|
|
return errorResult;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取探测器信息 | Get detector information
|
|
/// </summary>
|
|
public abstract DetectorInfo GetInfo();
|
|
|
|
// 模板方法,由子类实现 | Template methods, implemented by derived classes
|
|
protected abstract Task<DetectorResult> InitializeInternalAsync(CancellationToken cancellationToken);
|
|
protected abstract Task<DetectorResult> StartAcquisitionInternalAsync(CancellationToken cancellationToken);
|
|
protected abstract Task<DetectorResult> StopAcquisitionInternalAsync(CancellationToken cancellationToken);
|
|
protected abstract Task<DetectorResult> AcquireSingleFrameInternalAsync(CancellationToken cancellationToken);
|
|
protected abstract Task<DetectorResult> DarkCorrectionInternalAsync(int frameCount, CancellationToken cancellationToken);
|
|
protected abstract Task<DetectorResult> GainCorrectionInternalAsync(int frameCount, CancellationToken cancellationToken);
|
|
protected abstract Task<DetectorResult> AutoCorrectionInternalAsync(int frameCount, CancellationToken cancellationToken);
|
|
protected abstract Task<DetectorResult> BadPixelCorrectionInternalAsync(CancellationToken cancellationToken);
|
|
|
|
/// <summary>
|
|
/// 更新状态并发布事件 | Update status and publish event
|
|
/// </summary>
|
|
/// <param name="newStatus">新状态 | New status</param>
|
|
/// <summary>
|
|
/// 更新状态并发布事件 | Update status and publish event
|
|
/// 验证状态转换的合法性 | Validate state transition legality
|
|
/// </summary>
|
|
/// <param name="newStatus">新状态 | New status</param>
|
|
protected void UpdateStatus(DetectorStatus newStatus)
|
|
{
|
|
lock (_statusLock)
|
|
{
|
|
// 验证状态转换的合法性 | Validate state transition legality
|
|
if (!IsValidStateTransition(_status, newStatus))
|
|
{
|
|
var errorMsg = $"非法的状态转换:{_status} -> {newStatus} | Invalid state transition: {_status} -> {newStatus}";
|
|
PublishError(DetectorResult.Failure(errorMsg));
|
|
return;
|
|
}
|
|
|
|
if (_status != newStatus)
|
|
{
|
|
var oldStatus = _status;
|
|
_status = newStatus;
|
|
_eventAggregator.GetEvent<StatusChangedEvent>().Publish(newStatus);
|
|
|
|
// 记录状态转换日志(如果需要)| Log state transition (if needed)
|
|
System.Diagnostics.Debug.WriteLine($"状态转换 | State transition: {oldStatus} -> {newStatus}");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 验证状态转换是否合法 | Validate if state transition is legal
|
|
/// </summary>
|
|
/// <param name="currentStatus">当前状态 | Current status</param>
|
|
/// <param name="newStatus">新状态 | New status</param>
|
|
/// <returns>是否合法 | Whether it's legal</returns>
|
|
private bool IsValidStateTransition(DetectorStatus currentStatus, DetectorStatus newStatus)
|
|
{
|
|
// 相同状态总是允许的 | Same state is always allowed
|
|
if (currentStatus == newStatus)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// 定义合法的状态转换规则 | Define legal state transition rules
|
|
return (currentStatus, newStatus) switch
|
|
{
|
|
// 从未初始化状态只能转到初始化中 | From Uninitialized can only go to Initializing
|
|
(DetectorStatus.Uninitialized, DetectorStatus.Initializing) => true,
|
|
|
|
// 从初始化中可以转到就绪或错误 | From Initializing can go to Ready or Error
|
|
(DetectorStatus.Initializing, DetectorStatus.Ready) => true,
|
|
(DetectorStatus.Initializing, DetectorStatus.Error) => true,
|
|
|
|
// 从就绪状态可以转到采集中、校正中 | From Ready can go to Acquiring or Correcting
|
|
(DetectorStatus.Ready, DetectorStatus.Acquiring) => true,
|
|
(DetectorStatus.Ready, DetectorStatus.Correcting) => true,
|
|
|
|
// 从采集中可以转到就绪或错误 | From Acquiring can go to Ready or Error
|
|
(DetectorStatus.Acquiring, DetectorStatus.Ready) => true,
|
|
(DetectorStatus.Acquiring, DetectorStatus.Error) => true,
|
|
|
|
// 从校正中可以转到就绪或错误 | From Correcting can go to Ready or Error
|
|
(DetectorStatus.Correcting, DetectorStatus.Ready) => true,
|
|
(DetectorStatus.Correcting, DetectorStatus.Error) => true,
|
|
|
|
// 从错误状态可以转到初始化中(重新初始化)| From Error can go to Initializing (re-initialize)
|
|
(DetectorStatus.Error, DetectorStatus.Initializing) => true,
|
|
|
|
// 任何状态都可以转到错误状态 | Any state can go to Error
|
|
(_, DetectorStatus.Error) => true,
|
|
|
|
// 其他转换都是非法的 | All other transitions are illegal
|
|
_ => false
|
|
};
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 发布错误事件 | Publish error event
|
|
/// </summary>
|
|
/// <param name="result">错误结果 | Error result</param>
|
|
protected void PublishError(DetectorResult result)
|
|
{
|
|
_eventAggregator.GetEvent<ErrorOccurredEvent>().Publish(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发布图像采集事件 | Publish image captured event
|
|
/// </summary>
|
|
/// <param name="args">事件参数 | Event arguments</param>
|
|
protected void PublishImageCaptured(ImageCapturedEventArgs args)
|
|
{
|
|
_eventAggregator.GetEvent<ImageCapturedEvent>().Publish(args);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发布校正完成事件 | Publish correction completed event
|
|
/// </summary>
|
|
/// <param name="type">校正类型 | Correction type</param>
|
|
/// <param name="result">校正结果 | Correction result</param>
|
|
protected void PublishCorrectionCompleted(CorrectionType type, DetectorResult result)
|
|
{
|
|
_eventAggregator.GetEvent<CorrectionCompletedEvent>().Publish(
|
|
new CorrectionCompletedEventArgs(type, result));
|
|
}
|
|
|
|
// IDisposable 实现 | IDisposable implementation
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 释放资源 | Dispose resources
|
|
/// </summary>
|
|
/// <param name="disposing">是否释放托管资源 | Whether to dispose managed resources</param>
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (!_disposed)
|
|
{
|
|
if (disposing)
|
|
{
|
|
// 释放托管资源 | Release managed resources
|
|
}
|
|
// 释放非托管资源 | Release unmanaged resources
|
|
_disposed = true;
|
|
}
|
|
}
|
|
}
|
|
}
|