using AI.Common; using AI.Common.Log; using AIDiagnosis.Common.Enums; using AIDiagnosis.Common.Models; using AutoIVCCalculationLib; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Threading; using Vinno.AI.AutoIVCDiagnosisSDK.Interfaces; using Vinno.AI.AutoIVCDiagnosisSDK.Models; using Vinno.AI.AutoIVCDiagnosisService.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; using AutoIVCDiagnosis = AutoIVCDiagnosisSDK.AutoIVCDiagnosis; namespace Vinno.AI.AutoIVCDiagnosisService { public class AutoIVCDiagnosisService : IAutoIVCDiagnosisService, IDisposable, IEngine { private readonly ConcurrentStack _singleImageCache; private readonly string _modelFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks"); private PipeServer _singleImagePipeServer; private AutoIVCDiagnosis _autoIVCDiagnosis; private ImageProvider _imageProvider; private bool _disposed; public static List AllFunctions { get; } static AutoIVCDiagnosisService() { AllFunctions = AutoIVCDiagnosis.AllFunctions; } public static void Init(FunctionInfo enableFunction, FunctionInfo currentUsedFunction) { AutoIVCDiagnosis.Init(enableFunction, currentUsedFunction); } public AutoIVCDiagnosisService() { try { _singleImageCache = new ConcurrentStack(); _singleImagePipeServer = new PipeServer(AIDiagnosisSystemConsts.PipeForAutoIVCDiagnosisSingleImage); _singleImagePipeServer.LogMsgThrow += OnLogMsgThrow; _singleImagePipeServer.DataReceived += OnDataReceived; _singleImagePipeServer.StartAndReceive(); _imageProvider = new ImageProvider(AIEnumType.AutoIVCDiagnosis); } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-Constructor error:{ex}"); } } public void Initialize(AutoIVCDiagnosisParameter autoIVCParameter, bool hasImageProvider) { try { CloseDiagnosis(); var cpuNumber = autoIVCParameter.CPUNumber; var isIncludeContour = autoIVCParameter.IsIncludeCountour; var detectMode = (EnumDetectMode)autoIVCParameter.DetectMode; var detectTps = autoIVCParameter.DetectTps; var intervalTime = autoIVCParameter.IntervalTime; var cmPerPixel = autoIVCParameter.CmPerPixel; _autoIVCDiagnosis = new AutoIVCDiagnosis(Setting.Instance.IsSaveDetectImage, Setting.Instance.IsSaveAllImage, Logger.LogDir, hasImageProvider ? _imageProvider : null, cpuNumber, _modelFolder, isIncludeContour, cmPerPixel, detectMode, detectTps, intervalTime); _autoIVCDiagnosis.StartEvaluation += OnStartEvaluation; _autoIVCDiagnosis.FinishEvaluation += OnFinishEvaluation; _autoIVCDiagnosis.NotifyError += OnNotifyError; _autoIVCDiagnosis.NotifyLog += OnNotifyLog; } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-Initialize error:{ex}"); } } /// /// 切换引擎 /// /// public void SwitchEngines(FunctionInfo functionInfo) { try { AutoIVCDiagnosis.SwitchAIEngines(functionInfo); if (_autoIVCDiagnosis != null) { _autoIVCDiagnosis.SwitchAIEngines2(functionInfo); } } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-SwitchEngines error:{ex}"); } } public void Start() { try { if (_autoIVCDiagnosis != null) { _autoIVCDiagnosis.Start(); } } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-Start error:{ex}"); } } public void Stop() { try { if (_autoIVCDiagnosis != null) { _autoIVCDiagnosis.Stop(); } } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-Stop error:{ex}"); } } private void OnDataReceived(object sender, byte[] e) { try { _singleImageCache.Push(e); } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-OnDataReceived error:{ex}"); } } public void SetDetectTps(int detectTps) { try { if (_autoIVCDiagnosis != null) { _autoIVCDiagnosis.DetectTps = detectTps; } } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-SetDetectTps error:{ex}"); } } public void SetIntervalTime(int intervalTime) { try { if (_autoIVCDiagnosis != null) { _autoIVCDiagnosis.IntervalTime = intervalTime; } } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-SetIntervalTime error:{ex}"); } } public void SetDetectMode(AIEnumDetectMode detectMode) { try { if (_autoIVCDiagnosis != null) { _autoIVCDiagnosis.DetectMode = (EnumDetectMode)detectMode; } } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-SetDetectMode error:{ex}"); } } /// /// 设置一个像素代表的实际物理距离是多少cm /// /// public void SetCmPerPixel(float cmPerPixel) { try { if (_autoIVCDiagnosis != null) { _autoIVCDiagnosis.CmPerPixel = cmPerPixel; } } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-SetCmPerPixel error:{ex}"); } } public string StartAutoIVCCalculation(double ivcCurveTotalTime, float cmPerPixel, double intervalTime) { try { return _autoIVCDiagnosis?.StartAutoIVCCalculation(ivcCurveTotalTime, cmPerPixel, intervalTime); } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-StartAutoIVCCalculation error:{ex}"); return null; } } /// /// 检测单张Byte Image /// /// 图像输入的真实时间戳 /// public AIIVCCurveInfos DetectOneByteImage(string calcultationId, double realFrameTime) { try { byte[] byteImage = null; int retryCount = 0; while (!_singleImageCache.TryPop(out byteImage) && retryCount < 50) { Thread.Sleep(10); retryCount++; } if (byteImage == null) { Logger.Error($"AutoIVCDiagnosisService-DetectOneByteImage Get Image Cache Fail"); return null; } var ivcCurveInfos = _autoIVCDiagnosis?.DetectOneImage(calcultationId, byteImage, realFrameTime); return AIConvertHelper.ConvertIVCCurveInfosToAIIVCCurveInfos(ivcCurveInfos); } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-DetectOneByteImage error:{ex}"); return null; } } public AIIVCCurveInfos DetectOneRawImage(string calcultationId, int height, int width, AIEnumColorType colorType, double realFrameTime) { try { byte[] byteImage = null; int retryCount = 0; while (!_singleImageCache.TryPop(out byteImage) && retryCount < 50) { Thread.Sleep(10); retryCount++; } if (byteImage == null) { Logger.Error($"AutoIVCDiagnosisService-DetectOneRawImage Get Image Cache Fail"); return null; } var rawImage = new RawImage(byteImage, width, height, (EnumColorType)colorType); var ivcCurveInfos = _autoIVCDiagnosis?.DetectOneImage(calcultationId, rawImage, realFrameTime); return AIConvertHelper.ConvertIVCCurveInfosToAIIVCCurveInfos(ivcCurveInfos); } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-DetectOneRawImage error:{ex}"); return null; } } public void DetectOneByteImageAsync(string calculationId, double realFrameTime) { try { byte[] byteImage = null; int retryCount = 0; while (!_singleImageCache.TryPop(out byteImage) && retryCount < 50) { Thread.Sleep(10); retryCount++; } if (byteImage == null) { Logger.Error($"AutoIVCDiagnosisService-DetectOneByteImageAsync Get Image Cache Fail"); return; } _autoIVCDiagnosis?.DetectOneImageAsync(calculationId, byteImage, realFrameTime); } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-DetectOneByteImageAsync error:{ex}"); } } public void DetectOneRawImageAsync(string calculationId, int height, int width, AIEnumColorType colorType, double realFrameTime) { try { byte[] byteImage = null; int retryCount = 0; while (!_singleImageCache.TryPop(out byteImage) && retryCount < 50) { Thread.Sleep(10); retryCount++; } if (byteImage == null) { Logger.Error($"AutoIVCDiagnosisService-DetectOneRawImageAsync Get Image Cache Fail"); return; } var rawImage = new RawImage(byteImage, width, height, (EnumColorType)colorType); _autoIVCDiagnosis?.DetectOneImageAsync(calculationId, rawImage, realFrameTime); } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-DetectOneRawImageAsync error:{ex}"); } } public AIIVCCurveInfos StopAutoIVCCalculation(string calculationId) { try { var ivcCurveInfos = _autoIVCDiagnosis?.StopAutoIVCCalculation(calculationId); return AIConvertHelper.ConvertIVCCurveInfosToAIIVCCurveInfos(ivcCurveInfos); } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-StopAutoIVCCalculation 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($"AutoIVCDiagnosisService-SendRawImageData error:{ex}"); } } /// /// Send Byte Image Data For Pipe /// public void SendByteImageData() { try { _imageProvider?.ReceiveByteImageData(); } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-SendByteImageData error:{ex}"); } } public void Close() { try { Logger.Info($"AutoIVCDiagnosisService-Close Invoke"); CloseDiagnosis(); } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-Close error:{ex}"); } } private void CloseDiagnosis() { if (_autoIVCDiagnosis != null) { _autoIVCDiagnosis.StartEvaluation -= OnStartEvaluation; _autoIVCDiagnosis.FinishEvaluation -= OnFinishEvaluation; _autoIVCDiagnosis.NotifyError -= OnNotifyError; _autoIVCDiagnosis.NotifyLog -= OnNotifyLog; _autoIVCDiagnosis.Close(); _autoIVCDiagnosis = null; } } public void Dispose() { try { if (!_disposed) { Logger.Info($"AutoIVCDiagnosisService-Start Dispose"); CloseDiagnosis(); if (_singleImagePipeServer != null) { _singleImagePipeServer.DataReceived -= OnDataReceived; _singleImagePipeServer.Dispose(); _singleImagePipeServer.LogMsgThrow -= OnLogMsgThrow; _singleImagePipeServer = null; } _imageProvider.Dispose(); _imageProvider = null; _disposed = true; Logger.Info($"AutoIVCDiagnosisService Dispose End"); } } catch (Exception ex) { Logger.Error($"AutoIVCDiagnosisService-Dispose error:{ex}"); } } private void OnNotifyLog(object sender, LogEventArgs e) { if (e == null) { return; } switch (e.LogType) { case EnumLogType.InfoLog: Logger.Info($"AutoIVCDiagnosisService OnNotifyLog:{e.Msg}"); break; case EnumLogType.WarnLog: Logger.Warning($"AutoIVCDiagnosisService OnNotifyLog:{e.Msg}"); break; case EnumLogType.ErrorLog: case EnumLogType.FatalLog: default: Logger.Error($"AutoIVCDiagnosisService OnNotifyLog:{e.Msg}"); break; } var logEventArgs = AICommonServiceConvertHelper.ConvertLogEventArgsToAILogEventArgs(e); NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.AutoIVCDiagnosisNotifyLogRaised, Params = logEventArgs }); } private void OnNotifyError(object sender, ErrorEventArgs e) { Logger.Error($"AutoIVCDiagnosisService OnNotifyError:{e.GetException()}"); var logEventArgs = AICommonServiceConvertHelper.ConvertErrorEventArgsToAILogEventArgs(e); NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.AutoIVCDiagnosisNotifyLogRaised, 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; } } private void OnStartEvaluation(object sender, EventArgs e) { NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.AutoIVCDiagnosisStartEvaluationRaised, Params = e }); } private void OnFinishEvaluation(object sender, IVCCurveInfos e) { var aiIVCCurveInfos = AIConvertHelper.ConvertIVCCurveInfosToAIIVCCurveInfos(e); NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.AutoIVCDiagnosisFinishEvaluationRaised, Params = aiIVCCurveInfos }); } } }