VisionStaticAccuracyAnalyzerViewModel.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. using Cognex.VisionPro;
  2. using Cognex.VisionPro.ToolBlock;
  3. using MaterialDesignThemes.Wpf;
  4. using Prism.Commands;
  5. using Prism.Events;
  6. using Prism.Ioc;
  7. using Prism.Mvvm;
  8. using Prism.Regions;
  9. using Prism.Services.Dialogs;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Data;
  13. using System.Linq;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. using Team.FFFeederService;
  17. using Team.FFFeederService.Interfaces;
  18. using TeamAAS_VP.Core;
  19. using TeamAAS_VP.Data;
  20. using TeamAAS_VP.Enums;
  21. using TeamAAS_VP.Events;
  22. using TeamAAS_VP.Interfaces;
  23. using TeamAAS_VP.Models;
  24. using TeamAAS_VP.Models.Calibration;
  25. using TeamAAS_VP.Resources.Languages;
  26. using TeamAAS_VP.Services;
  27. using TeamAAS_VP.Views.Setting;
  28. namespace TeamAAS_VP.ViewModels.Product
  29. {
  30. public class VisionStaticAccuracyAnalyzerViewModel : BindableBase, IDialogAware
  31. {
  32. IRegionManager _regionManager;
  33. IEventAggregator _eventAggregator;
  34. IContainerProvider _container;
  35. IDialogService _dialogService;
  36. IFeederService _feederService;
  37. IRobotService _robotService;
  38. ICameraService _cameraService;
  39. ISystemDatabaseService _systemDatabaseService;
  40. //测试过程中控制取消的CTS
  41. CancellationTokenSource _cts;
  42. #region 属性
  43. private ICogImage _Image;
  44. public ICogImage Image
  45. {
  46. get { return _Image; }
  47. set { SetProperty(ref _Image, value); }
  48. }
  49. private Cognex.VisionPro.CogGraphicCollection _Graphic;
  50. public Cognex.VisionPro.CogGraphicCollection Graphic
  51. {
  52. get { return _Graphic; }
  53. set { SetProperty(ref _Graphic, value); }
  54. }
  55. private ProcedureModel _SelectProcedure;
  56. /// <summary>
  57. /// 选中的流程
  58. /// </summary>
  59. public ProcedureModel SelectProcedure
  60. {
  61. get { return _SelectProcedure; }
  62. set
  63. {
  64. SetProperty(ref _SelectProcedure, value);
  65. }
  66. }
  67. private ICamera _Camera;
  68. public ICamera Camera
  69. {
  70. get { return _Camera; }
  71. set { SetProperty(ref _Camera, value); }
  72. }
  73. private string _Message = "等待开始...";
  74. public string Message
  75. {
  76. get { return _Message; }
  77. set { SetProperty(ref _Message, value); }
  78. }
  79. private bool _IsRunning;
  80. public bool IsRunning
  81. {
  82. get { return _IsRunning; }
  83. set { SetProperty(ref _IsRunning, value); }
  84. }
  85. private CogToolBlock _VisionTool;
  86. public CogToolBlock VisionTool
  87. {
  88. get { return _VisionTool; }
  89. set { SetProperty(ref _VisionTool, value); }
  90. }
  91. private int _RepeatCount = 10;
  92. /// <summary>
  93. /// 重复次数
  94. /// </summary>
  95. public int RepeatCount
  96. {
  97. get { return _RepeatCount; }
  98. set { SetProperty(ref _RepeatCount, value); }
  99. }
  100. private int _CurrentProgress;
  101. /// <summary>
  102. /// 当前进度
  103. /// </summary>
  104. public int CurrentProgress
  105. {
  106. get { return _CurrentProgress; }
  107. set { SetProperty(ref _CurrentProgress, value); }
  108. }
  109. private int _SuccessCount;
  110. /// <summary>
  111. /// 成功次数
  112. /// </summary>
  113. public int SuccessCount
  114. {
  115. get { return _SuccessCount; }
  116. set { SetProperty(ref _SuccessCount, value); }
  117. }
  118. private int _FailCount;
  119. /// <summary>
  120. /// 失败次数
  121. /// </summary>
  122. public int FailCount
  123. {
  124. get { return _FailCount; }
  125. set { SetProperty(ref _FailCount, value); }
  126. }
  127. private double _SuccessRate;
  128. /// <summary>
  129. /// 成功率
  130. /// </summary>
  131. public double SuccessRate
  132. {
  133. get { return _SuccessRate; }
  134. set { SetProperty(ref _SuccessRate, value); }
  135. }
  136. //测试结果列表DataTable
  137. private DataTable _TestResult;
  138. public DataTable TestResult
  139. {
  140. get { return _TestResult; }
  141. set { SetProperty(ref _TestResult, value); }
  142. }
  143. private SnackbarMessageQueue _MessageQueue;
  144. public SnackbarMessageQueue MessageQueue
  145. {
  146. get { return _MessageQueue; }
  147. set { SetProperty(ref _MessageQueue, value); }
  148. }
  149. #endregion
  150. #region 命令
  151. private DelegateCommand _ConfirmCommand;
  152. public DelegateCommand ConfirmCommand =>
  153. _ConfirmCommand ?? (_ConfirmCommand = new DelegateCommand(ExecuteConfirmCommand).ObservesCanExecute(() => IsRunning));
  154. private DelegateCommand _CancelCommand;
  155. public DelegateCommand CancelCommand =>
  156. _CancelCommand ?? (_CancelCommand = new DelegateCommand(ExecuteCancelCommand).ObservesCanExecute(() => IsRunning));
  157. private DelegateCommand _StartTestCommand;
  158. public DelegateCommand StartTestCommand =>
  159. _StartTestCommand ?? (_StartTestCommand = new DelegateCommand(ExecuteStartTestCommand, CanExecuteStartTestCommand).ObservesProperty(() => IsRunning));
  160. private DelegateCommand _StopTestCommand;
  161. public DelegateCommand StopTestCommand =>
  162. _StopTestCommand ?? (_StopTestCommand = new DelegateCommand(() => { _cts?.Cancel(); }, () => IsRunning).ObservesProperty(() => IsRunning));
  163. //暂停测试命令
  164. private DelegateCommand _PauseTestCommand;
  165. public DelegateCommand PauseTestCommand =>
  166. _PauseTestCommand ?? (_PauseTestCommand = new DelegateCommand(() => { _cts?.Cancel(); }, () => IsRunning).ObservesProperty(() => IsRunning));
  167. private DelegateCommand _ExportCSVCommand;
  168. public DelegateCommand ExportCSVCommand =>
  169. _ExportCSVCommand ?? (_ExportCSVCommand = new DelegateCommand(ExecuteExportCSVCommand));
  170. private DelegateCommand _ExportReportCommand;
  171. public DelegateCommand ExportReportCommand =>
  172. _ExportReportCommand ?? (_ExportReportCommand = new DelegateCommand(ExecuteExportReportCommand));
  173. private DelegateCommand _ClearDataCommand;
  174. public DelegateCommand ClearDataCommand =>
  175. _ClearDataCommand ?? (_ClearDataCommand = new DelegateCommand(ExecuteClearDataCommand));
  176. #endregion
  177. #region 事件
  178. #endregion
  179. public VisionStaticAccuracyAnalyzerViewModel(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IDialogService dialogService,
  180. IFeederService feederService, IRobotService robotService, ICameraService cameraService, ISystemDatabaseService systemDatabaseService)
  181. {
  182. _regionManager = regionManager;
  183. _eventAggregator = ea;
  184. _container = container;
  185. _dialogService = dialogService;
  186. _feederService = feederService;
  187. _robotService = robotService;
  188. _cameraService = cameraService;
  189. _systemDatabaseService = systemDatabaseService;
  190. MessageQueue= new SnackbarMessageQueue(TimeSpan.FromSeconds(1));
  191. }
  192. #region 方法
  193. /// <summary>
  194. /// 确定
  195. /// </summary>
  196. void ExecuteConfirmCommand()
  197. {
  198. IDialogParameters parameters = new DialogParameters();
  199. //parameters.Add("Tool", Tool);
  200. //parameters.Add("RobotCameraRotationMatrix", RobotCameraRotationMatrix);
  201. //parameters.Add("Angle", Angle);
  202. RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters));
  203. }
  204. /// <summary>
  205. /// 取消
  206. /// </summary>
  207. void ExecuteCancelCommand()
  208. {
  209. IDialogParameters parameters = new DialogParameters();
  210. //parameters.Add("Tool", Tool);
  211. RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel, parameters));
  212. }
  213. /// <summary>
  214. /// 开始测试
  215. /// </summary>
  216. async void ExecuteStartTestCommand()
  217. {
  218. IsRunning = true;
  219. _cts = new CancellationTokenSource();
  220. CurrentProgress = 0;
  221. SuccessCount = 0;
  222. SuccessRate = 0;
  223. FailCount = 0;
  224. Message = "测试进行中...";
  225. try
  226. {
  227. while (CurrentProgress < RepeatCount)
  228. {
  229. if (_cts.Token.IsCancellationRequested)
  230. {
  231. Message = "测试已取消!";
  232. break;
  233. }
  234. await Task.Delay(1000);
  235. CurrentProgress++;
  236. SuccessCount++;
  237. SuccessRate = (double)SuccessCount / CurrentProgress * 100;
  238. SendTaskMessage($"测试进行中... {CurrentProgress}/{RepeatCount}");
  239. }
  240. if (CurrentProgress >= RepeatCount)
  241. {
  242. Message = "测试完成!";
  243. }
  244. }
  245. catch (Exception ex)
  246. {
  247. LogHelper.WriteLogError("视觉静态重复测试时出错!", ex);
  248. }
  249. finally
  250. {
  251. IsRunning = false;
  252. }
  253. }
  254. bool CanExecuteStartTestCommand()
  255. {
  256. return !IsRunning;
  257. }
  258. /// <summary>
  259. /// 清除数据
  260. /// </summary>
  261. void ExecuteClearDataCommand()
  262. {
  263. }
  264. /// <summary>
  265. /// 导出测试报告
  266. /// </summary>
  267. void ExecuteExportReportCommand()
  268. {
  269. }
  270. /// <summary>
  271. /// 导出测试数据为CSV文件
  272. /// </summary>
  273. void ExecuteExportCSVCommand()
  274. {
  275. }
  276. /// <summary>
  277. /// 执行相机拍照并运行 ToolBlock,返回是否成功并通过 out 参数返回 Outputs、图像和图形集合。
  278. /// </summary>
  279. /// <param name="outputCollection"></param>
  280. /// <param name="outImage"></param>
  281. /// <param name="outGraphicCollection"></param>
  282. /// <returns></returns>
  283. public bool ExecutePhotoEx(out CogToolBlockTerminalCollection outputCollection, out ICogImage outImage, out CogGraphicCollection outGraphicCollection)
  284. {
  285. outImage = null;
  286. outGraphicCollection = null;
  287. try
  288. {
  289. // 1. 采集图像
  290. bool succed = Camera.SetExposureTime(SelectProcedure.ExposureTime);
  291. if (!succed)
  292. {
  293. SendTaskMessage(Lang.相机曝光设置失败);
  294. }
  295. succed = Camera.SetGain(SelectProcedure.Gain);
  296. if (!succed)
  297. {
  298. SendTaskMessage(Lang.相机增益设置失败);
  299. }
  300. DateTime nowtime = DateTime.Now;
  301. LogHelper.WriteLogInfo(Lang.开始采集图像);
  302. var image = Camera.Grab();
  303. if (image == null)
  304. {
  305. SendTaskMessage(Lang.图像采集失败);
  306. outputCollection = null;
  307. return false;
  308. }
  309. outImage = image;
  310. VisionTool.Inputs["InputImage"].Value = image;
  311. LogHelper.WriteLogInfo(string.Format(Lang.采集图像完成用时0ms, (DateTime.Now - nowtime).Milliseconds));
  312. // 2. 为ToolBlock传入其他输入终端
  313. //if (InputTerminal != null)
  314. //{
  315. // LogHelper.WriteLogInfo(Lang.为ToolBlock传入输入终端);
  316. // foreach (var item in InputTerminal)
  317. // {
  318. // if (VisionTool.Inputs.Contains(item.Key))
  319. // {
  320. // LogHelper.WriteLogInfo($"传入[{item.Key}]={item.Value}");
  321. // VisionTool.Inputs[item.Key].Value = item.Value;
  322. // }
  323. // else
  324. // {
  325. // LogHelper.WriteLogInfo($"创建并传入[{item.Key}]={item.Value}");
  326. // VisionTool.Inputs.Add(new CogToolBlockTerminal(item.Key, item.Value));
  327. // }
  328. // }
  329. //}
  330. // 3. 运行视觉工具
  331. LogHelper.WriteLogInfo(Lang.开始运行视觉工具);
  332. VisionTool.Run(); //运行ToolBlock
  333. if (VisionTool.RunStatus.Result == CogToolResultConstants.Accept)
  334. {
  335. SendTaskMessage(Lang.视觉流程执行耗时.Replace("{0}", SelectProcedure.Name).Replace("{1}", $"{VisionTool.RunStatus.ProcessingTime:F1}"));
  336. outputCollection = VisionTool.Outputs; //获取输出终端集合
  337. ICogRecord record = null;
  338. foreach (CogToolBlockTerminal item in outputCollection)
  339. {
  340. if (item.Value is ICogRecord)
  341. record = item.Value as ICogRecord;
  342. }
  343. outGraphicCollection = outputCollection["Graphic"].Value as CogGraphicCollection;
  344. return true;
  345. }
  346. else
  347. {
  348. SendTaskMessage(Lang.视觉流程执行出错耗时.Replace("{0}", SelectProcedure.Name).Replace("{1}", $"{VisionTool.RunStatus.ProcessingTime:F1}"));
  349. SendTaskMessage(VisionTool.RunStatus.Message);
  350. outputCollection = null;
  351. outGraphicCollection = outputCollection["Graphic"].Value as CogGraphicCollection;
  352. return false;
  353. }
  354. }
  355. catch (Exception ex)
  356. {
  357. SendTaskMessage(ex.Message);
  358. LogHelper.WriteLogError(Lang.执行相机取图并执行视觉工具组时出错, ex);
  359. outputCollection = null;
  360. return false;
  361. }
  362. }
  363. public void SendTaskMessage(string msg)
  364. {
  365. App.Current.Dispatcher.Invoke(() =>
  366. {
  367. MessageQueue.Clear();
  368. MessageQueue.Enqueue(msg);
  369. });
  370. }
  371. /// <summary>
  372. /// 相机拍照
  373. /// </summary>
  374. /// <returns></returns>
  375. //private async Task<(bool IsSuccess, double X, double Y, double U, int ImageWidth, int ImageHeight)> CaptureAndProcess()
  376. //{
  377. // if (Feeder != null)
  378. // {
  379. // Feeder.OpenLight();
  380. // Feeder.SetLightTimeOut((ushort)SelectCalibration.Brightness);
  381. // }
  382. // await Task.Delay(200);
  383. // //采集图像
  384. // if (Camera != null)
  385. // {
  386. // SelectCalibration.ToolBlock.Inputs["InputImage"].Value = Camera.Grab();
  387. // }
  388. // App.Current.Dispatcher.Invoke(() =>
  389. // {
  390. // Graphic = null;
  391. // Image = (ICogImage)SelectCalibration.ToolBlock.Inputs["InputImage"].Value;
  392. // });
  393. // SelectCalibration.ToolBlock.Run();
  394. // CogToolBlockTerminalCollection outputCollection = SelectCalibration.ToolBlock.Outputs;
  395. // App.Current.Dispatcher.Invoke(() =>
  396. // {
  397. // Graphic = outputCollection["Graphic"].Value as CogGraphicCollection;
  398. // });
  399. // bool Found = (bool)(outputCollection["Found"].Value);
  400. // if (Found)
  401. // {
  402. // var strpoints = outputCollection["Point"].Value.ToString();
  403. // string[] items = strpoints.Split(',');
  404. // double x = double.Parse(items[0]);
  405. // double y = double.Parse(items[1]);
  406. // return (true, x, y, 0, Image.Width, Image.Height);
  407. // }
  408. // else
  409. // {
  410. // return (false, 0, 0, 0, Image.Width, Image.Height);
  411. // }
  412. //}
  413. #endregion
  414. #region 继承
  415. public string Title { get; set; } = "视觉静态精度分析仪";
  416. public event Action<IDialogResult> RequestClose;
  417. public bool CanCloseDialog()
  418. {
  419. return true;
  420. }
  421. public void OnDialogClosed()
  422. {
  423. }
  424. public void OnDialogOpened(IDialogParameters parameters)
  425. {
  426. SelectProcedure = parameters.GetValue<ProcedureModel>("SelectedProcedure");
  427. Camera = _cameraService.GetCamera(SelectProcedure.CameraId);
  428. VisionTool = parameters.GetValue<CogToolBlock>("ToolBlock");
  429. }
  430. #endregion
  431. }
  432. }