探测器XP.Hardware.Detector类库为了更好集成新的探测器,统一接口方法,DetectorService重构为通过统一接口;

新增暗场校正和亮场校正帧数配置属性(默认 64,范围 1-128),config 加载校正帧数;
修正探测器IsConnected连接状态的判断逻辑。
This commit is contained in:
QI Mingxuan
2026-05-21 13:19:30 +08:00
parent 119d03a02b
commit 2d7cf17a3b
12 changed files with 333 additions and 69 deletions
@@ -62,7 +62,11 @@ namespace XP.Hardware.Detector.Services
{
lock (_lock)
{
return _detector != null && _detector.Status != DetectorStatus.Uninitialized;
if (_detector == null) return false;
var status = _detector.Status;
return status == DetectorStatus.Ready
|| status == DetectorStatus.Acquiring
|| status == DetectorStatus.Correcting;
}
}
}
@@ -509,64 +513,44 @@ namespace XP.Hardware.Detector.Services
var detector = GetDetectorOrThrow();
// 通过 IVarexDetector 接口下发参数 | Apply parameters via IVarexDetector interface
if (detector is IVarexDetector varexDetector)
// 如果正在采集,先停止 | Stop acquisition first if running
bool wasAcquiring = detector.Status == DetectorStatus.Acquiring;
if (wasAcquiring)
{
// 如果正在采集,先停止(XISL SDK 不允许采集中修改参数| Stop acquisition first if running (XISL SDK does not allow parameter changes during acquisition)
bool wasAcquiring = detector.Status == DetectorStatus.Acquiring;
if (wasAcquiring)
_logger?.Info("探测器正在采集,先停止采集再应用参数 | Detector is acquiring, stopping before applying parameters");
var stopResult = await detector.StopAcquisitionAsync(cancellationToken);
if (!stopResult.IsSuccess)
{
_logger?.Info("探测器正在采集,先停止采集再应用参数 | Detector is acquiring, stopping before applying parameters");
var stopResult = await detector.StopAcquisitionAsync(cancellationToken);
if (!stopResult.IsSuccess)
{
_lastError = stopResult;
_logger?.Error(stopResult.Exception, "停止采集失败,无法应用参数:{Message} | Failed to stop acquisition, cannot apply parameters: {Message}", stopResult.ErrorMessage);
return DetectorResult.Failure($"停止采集失败,无法应用参数 | Failed to stop acquisition, cannot apply parameters: {stopResult.ErrorMessage}");
}
_lastError = stopResult;
_logger?.Error(stopResult.Exception, "停止采集失败,无法应用参数:{Message} | Failed to stop acquisition, cannot apply parameters: {Message}", stopResult.ErrorMessage);
return DetectorResult.Failure($"停止采集失败,无法应用参数 | Failed to stop acquisition, cannot apply parameters: {stopResult.ErrorMessage}");
}
// 设置 Binning | Set binning
var binningResult = await varexDetector.SetBinningModeAsync((BinningMode)binningIndex);
if (!binningResult.IsSuccess)
{
_lastError = binningResult;
return binningResult;
}
// 设置增益(PGA| Set gain (PGA)
var gainResult = await varexDetector.SetGainModeAsync((GainMode)pga);
if (!gainResult.IsSuccess)
{
_lastError = gainResult;
return gainResult;
}
// 设置曝光时间(帧率→微秒:1000*1000/帧率)| Set exposure time (frame rate → microseconds)
uint exposureUs = frameRate > 0 ? (uint)(1_000_000m / frameRate) : 66667;
var exposureResult = await varexDetector.SetExposureTimeAsync(exposureUs);
if (!exposureResult.IsSuccess)
{
_lastError = exposureResult;
return exposureResult;
}
// 如果之前在采集,恢复采集 | Resume acquisition if it was running before
if (wasAcquiring)
{
_logger?.Info("参数应用完成,恢复连续采集 | Parameters applied, resuming continuous acquisition");
var startResult = await detector.StartAcquisitionAsync(cancellationToken);
if (!startResult.IsSuccess)
{
_logger?.Warn("恢复采集失败:{Message}(参数已成功应用)| Failed to resume acquisition: {Message} (parameters were applied successfully)", startResult.ErrorMessage);
}
}
_logger?.Info("参数应用成功 | Parameters applied successfully");
return DetectorResult.Success("参数应用成功 | Parameters applied successfully");
}
return DetectorResult.Failure("当前探测器不支持参数下发 | Current detector does not support parameter application");
// 通过统一接口下发参数(不依赖具体探测器类型)| Apply parameters via unified interface (no dependency on specific detector type)
var result = await detector.ApplyParametersAsync(binningIndex, pga, frameRate, cancellationToken);
if (!result.IsSuccess)
{
_lastError = result;
_logger?.Error(result.Exception, "应用参数失败:{Message} | Apply parameters failed: {Message}", result.ErrorMessage);
}
else
{
_logger?.Info("参数应用成功 | Parameters applied successfully");
}
// 如果之前在采集,恢复采集 | Resume acquisition if it was running before
if (wasAcquiring)
{
_logger?.Info("参数应用完成,恢复连续采集 | Parameters applied, resuming continuous acquisition");
var startResult = await detector.StartAcquisitionAsync(cancellationToken);
if (!startResult.IsSuccess)
{
_logger?.Warn("恢复采集失败:{Message}(参数已成功应用)| Failed to resume acquisition: {Message} (parameters were applied successfully)", startResult.ErrorMessage);
}
}
return result;
}
catch (Exception ex)
{
@@ -640,6 +624,29 @@ namespace XP.Hardware.Detector.Services
return null;
}
/// <summary>
/// 获取当前探测器的校正能力描述 | Get correction capabilities of current detector
/// 未初始化时返回基于配置文件的默认值
/// </summary>
public CorrectionCapabilities GetCorrectionCapabilities()
{
lock (_lock)
{
if (_detector != null)
{
return _detector.GetCorrectionCapabilities();
}
}
// 未初始化时从配置文件构建默认值 | Build default from config when not initialized
var config = GetCurrentConfig();
return new CorrectionCapabilities
{
DarkFrameCount = config?.DarkCorrectionFrameCount ?? 64,
GainFrameCount = config?.GainCorrectionFrameCount ?? 64
};
}
/// <summary>
/// 获取探测器实例或抛出异常 | Get detector instance or throw exception
/// </summary>