using AI.Common; using AI.Common.Log; using AIDiagnosis.Common.Enums; using AIDiagnosis.Common.Models; using AutoVTICalculationLib; using AutoVTIDiagnosisSDK; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Threading; using Vinno.AI.AutoVTIDiagnosisSDK.Interfaces; using Vinno.AI.AutoVTIDiagnosisSDK.Models; using Vinno.AI.AutoVTIDiagnosisService.Tools; using Vinno.AI.CommonSDK.Enums; using Vinno.AI.CommonSDK.Models; using Vinno.AI.CommonSDK.Tools; using Vinno.AI.Service.Common.Interfaces; using Vinno.AI.Service.Common.Models; using Vinno.AI.Service.Common.Tools; namespace Vinno.AI.AutoVTIDiagnosisService { public class AutoVTIDiagnosisService : IAutoVTIDiagnosisService, IDisposable, IEngine { private readonly string _modelFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks"); private readonly ConcurrentStack _singleImageCache; private PipeServer _singleImagePipeServer; private ImageProvider _imageProvider; private AutoVTIDiagnosis _autoVTIDiagnosis; private bool _disposed; public static List AllFunctions { get; } static AutoVTIDiagnosisService() { AllFunctions = AutoVTIDiagnosis.AllFunctions; } public static void Init(FunctionInfo enableFunction, FunctionInfo currentUsedFunction) { AutoVTIDiagnosis.Init(enableFunction, currentUsedFunction); } public AutoVTIDiagnosisService() { try { _singleImageCache = new ConcurrentStack(); _singleImagePipeServer = new PipeServer(AIDiagnosisSystemConsts.PipeForAutoVTIDiagnosisSingleImage); _singleImagePipeServer.LogMsgThrow += OnLogMsgThrow; _singleImagePipeServer.DataReceived += OnDataReceived; _singleImagePipeServer.StartAndReceive(); _imageProvider = new ImageProvider(AIEnumType.AutoVTIDiagnosis); } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-Constructor error:{ex}"); } } private void OnDataReceived(object sender, byte[] e) { try { _singleImageCache.Push(e); } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-OnDataReceived error:{ex}"); } } public void Initialize(AutoVTIDiagnosisParameter autoVTIParameter, bool hasImageProvider) { try { CloseDiagnosis(); var cpuNumber = autoVTIParameter.CPUNumber; var detectMode = (EnumDetectMode)autoVTIParameter.DetectMode; var detectTps = autoVTIParameter.DetectTps; var intervalTime = autoVTIParameter.IntervalTime; var cmPerPixel = autoVTIParameter.CmPerPixel; var isIncludeContour = autoVTIParameter.IsIncludeCountour; _autoVTIDiagnosis = new AutoVTIDiagnosis(Setting.Instance.IsSaveDetectImage, Setting.Instance.IsSaveAllImage, Logger.LogDir, hasImageProvider ? _imageProvider : null, cpuNumber, _modelFolder, cmPerPixel, detectMode, detectTps, intervalTime, isIncludeContour); _autoVTIDiagnosis.StartEvaluation += OnStartEvaluation; _autoVTIDiagnosis.FinishEvaluation += OnFinishEvaluation; _autoVTIDiagnosis.NotifyError += OnNotifyError; _autoVTIDiagnosis.NotifyLog += OnNotifyLog; } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-Initialize error:{ex}"); } } /// /// 切换引擎 /// /// public void SwitchEngines(FunctionInfo functionInfo) { try { AutoVTIDiagnosis.SwitchAIEngines(functionInfo); if (_autoVTIDiagnosis != null) { _autoVTIDiagnosis.SwitchAIEngines2(functionInfo); } } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-SwitchEngines error:{ex}"); } } public void Start() { try { if (_autoVTIDiagnosis != null) { _autoVTIDiagnosis.Start(); } } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-Start error:{ex}"); } } public void Stop() { try { if (_autoVTIDiagnosis != null) { _autoVTIDiagnosis.Stop(); } } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-Stop error:{ex}"); } } public void SetDetectTps(int detectTps) { try { if (_autoVTIDiagnosis != null) { _autoVTIDiagnosis.DetectTps = detectTps; } } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-SetDetectTps error:{ex}"); } } public void SetIntervalTime(int intervalTime) { try { if (_autoVTIDiagnosis != null) { _autoVTIDiagnosis.IntervalTime = intervalTime; } } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-SetIntervalTime error:{ex}"); } } public void SetDetectMode(AIEnumDetectMode detectMode) { try { if (_autoVTIDiagnosis != null) { _autoVTIDiagnosis.DetectMode = (EnumDetectMode)detectMode; } } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-SetDetectMode error:{ex}"); } } /// /// 设置一个像素代表的实际物理距离是多少cm /// /// public void SetCmPerPixel(float cmPerPixel) { try { if (_autoVTIDiagnosis != null) { _autoVTIDiagnosis.CmPerPixel = cmPerPixel; } } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-SetCmPerPixel error:{ex}"); } } /// /// 检测单张Byte Image /// /// 图像上一个像素实际代表的物理距离是多少cm /// public AIAutoVTICalcResult DetectOneByteImage(float cmPerPixel) { try { byte[] byteImage = null; int retryCount = 0; while (!_singleImageCache.TryPop(out byteImage) && retryCount < 50) { Thread.Sleep(10); retryCount++; } if (byteImage == null) { Logger.Error($"AutoVTIDiagnosisService-DetectOneByteImage Get Image Cache Fail"); return null; } var autoVTICalculationResults = _autoVTIDiagnosis.DetectOneImage(byteImage, cmPerPixel); return AIConvertHelper.ConvertAutoVTICalcResultToAIAutoVTICalcResult(autoVTICalculationResults); } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-DetectOneByteImage error:{ex}"); return null; } } public AIAutoVTICalcResult DetectOneRawImage(int height, int width, AIEnumColorType colorType, float cmPerPixel) { try { byte[] byteImage = null; int retryCount = 0; while (!_singleImageCache.TryPop(out byteImage) && retryCount < 50) { Thread.Sleep(10); retryCount++; } if (byteImage == null) { Logger.Error($"AutoVTIDiagnosisService-DetectOneRawImage Get Image Cache Fail"); return null; } var rawImage = new RawImage(byteImage, width, height, (EnumColorType)colorType); var autoVTICalculationResults = _autoVTIDiagnosis.DetectOneImage(rawImage, cmPerPixel); return AIConvertHelper.ConvertAutoVTICalcResultToAIAutoVTICalcResult(autoVTICalculationResults); } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-DetectOneRawImage error:{ex}"); return null; } } /// /// Send Raw Image Data For Pipe /// /// /// /// public void SendRawImageData(int height, int width, AIEnumColorType colorType) { try { _imageProvider?.ReceiveRawImageData(height, width, (EnumColorType)colorType); } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-SendRawImageData error:{ex}"); } } /// /// Send Byte Image Data For Pipe /// public void SendByteImageData() { try { _imageProvider?.ReceiveByteImageData(); } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-SendByteImageData error:{ex}"); } } public void Close() { try { Logger.Info($"AutoVTIDiagnosisService-Close Invoke"); CloseDiagnosis(); } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-Close error:{ex}"); } } private void CloseDiagnosis() { if (_autoVTIDiagnosis != null) { _autoVTIDiagnosis.StartEvaluation -= OnStartEvaluation; _autoVTIDiagnosis.FinishEvaluation -= OnFinishEvaluation; _autoVTIDiagnosis.NotifyError -= OnNotifyError; _autoVTIDiagnosis.NotifyLog -= OnNotifyLog; _autoVTIDiagnosis.Close(); _autoVTIDiagnosis = null; } } public void Dispose() { try { if (!_disposed) { Logger.Info($"AutoVTIDiagnosisService-Start Dispose"); CloseDiagnosis(); if (_singleImagePipeServer != null) { _singleImagePipeServer.DataReceived -= OnDataReceived; _singleImagePipeServer.Dispose(); _singleImagePipeServer.LogMsgThrow -= OnLogMsgThrow; _singleImagePipeServer = null; } _imageProvider.Dispose(); _imageProvider = null; _disposed = true; Logger.Info($"AutoVTIDiagnosisService Dispose End"); } } catch (Exception ex) { Logger.Error($"AutoVTIDiagnosisService-Dispose error:{ex}"); } } private void OnStartEvaluation(object sender, EventArgs e) { NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.AutoVTIDiagnosisStartEvaluationRaised, Params = e }); } private void OnFinishEvaluation(object sender, AutoVTICalcResult e) { var aiAutoVTICalculationResults = AIConvertHelper.ConvertAutoVTICalcResultToAIAutoVTICalcResult(e); NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.AutoVTIDiagnosisFinishEvaluationRaised, Params = aiAutoVTICalculationResults }); } private void OnNotifyLog(object sender, LogEventArgs e) { if (e == null) { return; } switch (e.LogType) { case EnumLogType.InfoLog: Logger.Info($"AutoVTIDiagnosisService OnNotifyLog:{e.Msg}"); break; case EnumLogType.WarnLog: Logger.Warning($"AutoVTIDiagnosisService OnNotifyLog:{e.Msg}"); break; case EnumLogType.ErrorLog: case EnumLogType.FatalLog: default: Logger.Error($"AutoVTIDiagnosisService OnNotifyLog:{e.Msg}"); break; } var logEventArgs = AICommonServiceConvertHelper.ConvertLogEventArgsToAILogEventArgs(e); NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.AutoVTIDiagnosisNotifyLogRaised, Params = logEventArgs }); } private void OnNotifyError(object sender, ErrorEventArgs e) { Logger.Error($"AutoVTIDiagnosisService OnNotifyError:{e.GetException()}"); var logEventArgs = AICommonServiceConvertHelper.ConvertErrorEventArgsToAILogEventArgs(e); NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.AutoVTIDiagnosisNotifyLogRaised, Params = logEventArgs }); } private void OnLogMsgThrow(object sender, AILogEventArgs e) { if (e == null) { return; } switch (e.LogType) { case AIEnumLogType.ErrorLog: case AIEnumLogType.FatalLog: Logger.Error(e.Msg); break; case AIEnumLogType.WarnLog: Logger.Warning(e.Msg); break; case AIEnumLogType.InfoLog: default: Logger.Info(e.Msg); break; } } } }