FeederParamsViewModel.cs 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. using Cognex.VisionPro;
  2. using Cognex.VisionPro.ToolBlock;
  3. using MaterialDesignThemes.Wpf;
  4. using MathNet.Numerics.LinearAlgebra;
  5. using OpenCvSharp;
  6. using Prism.Commands;
  7. using Prism.Events;
  8. using Prism.Ioc;
  9. using Prism.Mvvm;
  10. using Prism.Regions;
  11. using Prism.Services.Dialogs;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Collections.ObjectModel;
  15. using System.Drawing;
  16. using System.Linq;
  17. using System.Threading;
  18. using System.Threading.Tasks;
  19. using System.Web.UI.WebControls;
  20. using System.Windows;
  21. using System.Windows.Media.Imaging;
  22. using Team.FFFeederService;
  23. using Team.FFFeederService.Interfaces;
  24. using Team.FFFeederService.Models;
  25. using TeamAAS_VP;
  26. using TeamAAS_VP.Controls;
  27. using TeamAAS_VP.Core;
  28. using TeamAAS_VP.Enums;
  29. using TeamAAS_VP.Events;
  30. using TeamAAS_VP.Models;
  31. using TeamAAS_VP.Resources.Languages;
  32. using TeamAAS_VP.Views.Product;
  33. namespace TeamAAS_VP.ViewModels.Product
  34. {
  35. public class FeederParamsViewModel : BindableBase
  36. {
  37. IRegionManager _regionManager;
  38. IEventAggregator _eventAggregator;
  39. IContainerProvider _container;
  40. IDialogService _dialogService;
  41. ProductsViewModel productsViewModel;
  42. CancellationTokenSource TokenSource;
  43. CancellationTokenSource AutoFindVirCTS;
  44. #region 属性
  45. private ProductModel _SelectProduct;
  46. /// <summary>
  47. /// 选中的产品
  48. /// </summary>
  49. public ProductModel SelectProduct
  50. {
  51. get { return _SelectProduct; }
  52. set { SetProperty(ref _SelectProduct, value); }
  53. }
  54. private ProcedureModel _SelectProcedure;
  55. /// <summary>
  56. /// 选中的流程
  57. /// </summary>
  58. public ProcedureModel SelectProcedure
  59. {
  60. get { return _SelectProcedure; }
  61. set { SetProperty(ref _SelectProcedure, value); }
  62. }
  63. private int _SelectFeederFunctionIndex;
  64. public int SelectFeederFunctionIndex
  65. {
  66. get { return _SelectFeederFunctionIndex; }
  67. set
  68. {
  69. SetProperty(ref _SelectFeederFunctionIndex, value);
  70. if (value >= 0 && value <= 25)
  71. {
  72. SelectFeederFunction = (VibrationFunction)value;
  73. }
  74. else
  75. {
  76. SelectFeederFunction = VibrationFunction.Delay;
  77. }
  78. }
  79. }
  80. private VibrationFunction _SelectFeederFunction;
  81. /// <summary>
  82. /// 选中的feeder振动功能码
  83. /// </summary>
  84. public VibrationFunction SelectFeederFunction
  85. {
  86. get { return _SelectFeederFunction; }
  87. set { SetProperty(ref _SelectFeederFunction, value); }
  88. }
  89. private int _SelectStockFeederFunctionIndex;
  90. public int SelectStockFeederFunctionIndex
  91. {
  92. get { return _SelectStockFeederFunctionIndex; }
  93. set
  94. {
  95. SetProperty(ref _SelectStockFeederFunctionIndex, value);
  96. if (value >= 0 && value <= 25)
  97. {
  98. SelectStockFeederFunction = (VibrationFunction)value;
  99. }
  100. else
  101. {
  102. SelectStockFeederFunction = VibrationFunction.Delay;
  103. }
  104. }
  105. }
  106. private VibrationFunction _SelectStockFunction;
  107. /// <summary>
  108. /// 选中的feeder料仓功能码
  109. /// </summary>
  110. public VibrationFunction SelectStockFunction
  111. {
  112. get { return _SelectStockFunction; }
  113. set { SetProperty(ref _SelectStockFunction, value); }
  114. }
  115. private VibrationFunction _SelectStockFeederFunction;
  116. /// <summary>
  117. /// 选中的feeder料仓振动盘功能码
  118. /// </summary>
  119. public VibrationFunction SelectStockFeederFunction
  120. {
  121. get { return _SelectStockFeederFunction; }
  122. set { SetProperty(ref _SelectStockFeederFunction, value); }
  123. }
  124. public Management management { get; set; }
  125. public FeederService feederService { get; set; }
  126. private IVoiceCoilMotorFeeder _Feeder;
  127. public IVoiceCoilMotorFeeder Feeder
  128. {
  129. get { return _Feeder; }
  130. set { SetProperty(ref _Feeder, value); }
  131. }
  132. private int _SelectActionIndex = -1;
  133. /// <summary>
  134. /// Feeder动作索引
  135. /// </summary>
  136. public int SelectActionIndex
  137. {
  138. get { return _SelectActionIndex; }
  139. set
  140. {
  141. SetProperty(ref _SelectActionIndex, value);
  142. if (value >= 0 && SelectProcedure.FeederFindFrequency != null && SelectProcedure.FeederFindFrequency.FeederFindFrequency != null)
  143. {
  144. SelectedActionParam = SelectProcedure.FeederFindFrequency.FeederFindFrequency.FirstOrDefault(f => f.ActionIndex == value);
  145. if (SelectedActionParam.AmplitudeMax == SelectedActionParam.AmplitudeMin || SelectedActionParam.FrequencyMax == SelectedActionParam.FrequencyMin)
  146. {
  147. AutoAdjustmentParameter findVirTask = new AutoAdjustmentParameter(Feeder, SelectedActionParam.ActionIndex, ExecuteVisualPhoto);
  148. var defultpar = findVirTask.detector.GetLogicParameters();
  149. SelectedActionParam.AmplitudeMax = defultpar.u16MaxAmp;
  150. SelectedActionParam.AmplitudeMin = defultpar.u16MinAmp;
  151. SelectedActionParam.FrequencyMax = defultpar.u16MaxFre;
  152. SelectedActionParam.FrequencyMin = defultpar.u16MinFre;
  153. SelectedActionParam.Duration= defultpar.u16Tim;
  154. findVirTask.Dispose();
  155. }
  156. }
  157. else
  158. {
  159. SelectedActionParam = null;
  160. }
  161. }
  162. }
  163. private ActionParamsExtModel _SelectedActionParam;
  164. public ActionParamsExtModel SelectedActionParam
  165. {
  166. get { return _SelectedActionParam; }
  167. set { SetProperty(ref _SelectedActionParam, value); }
  168. }
  169. private bool _InExecutionFindVibP;
  170. /// <summary>
  171. /// 正在执行自动寻找振动参数
  172. /// </summary>
  173. public bool InExecutionFindVibP
  174. {
  175. get { return _InExecutionFindVibP; }
  176. set { SetProperty(ref _InExecutionFindVibP, value); }
  177. }
  178. private BitmapSource _CameraImage;
  179. public BitmapSource CameraImage
  180. {
  181. get { return _CameraImage; }
  182. set { SetProperty(ref _CameraImage, value); }
  183. }
  184. private bool _FeederDirectionInverse;
  185. public bool FeederDirectionInverse
  186. {
  187. get { return _FeederDirectionInverse; }
  188. set { SetProperty(ref _FeederDirectionInverse, value); }
  189. }
  190. private SingleActionParam _SingleActionParam=new SingleActionParam();
  191. /// <summary>
  192. /// 自动调频时的动作参数
  193. /// </summary>
  194. public SingleActionParam SingleActionParam
  195. {
  196. get { return _SingleActionParam; }
  197. set { SetProperty(ref _SingleActionParam, value); }
  198. }
  199. private string _StateMesg;
  200. public string StateMesg
  201. {
  202. get { return _StateMesg; }
  203. set { SetProperty(ref _StateMesg, value); }
  204. }
  205. #endregion
  206. #region 命令
  207. private DelegateCommand _NextCommand;
  208. public DelegateCommand NextCommand =>
  209. _NextCommand ?? (_NextCommand = new DelegateCommand(ExecuteNextCommand));
  210. private DelegateCommand _BackCommand;
  211. public DelegateCommand BackCommand =>
  212. _BackCommand ?? (_BackCommand = new DelegateCommand(ExecuteBackCommand));
  213. private DelegateCommand _AddFunctionCommand;
  214. public DelegateCommand AddFunctionCommand =>
  215. _AddFunctionCommand ?? (_AddFunctionCommand = new DelegateCommand(ExecuteAddFunctionCommand));
  216. private DelegateCommand<object> _RemoveFunctionCommand;
  217. public DelegateCommand<object> RemoveFunctionCommand =>
  218. _RemoveFunctionCommand ?? (_RemoveFunctionCommand = new DelegateCommand<object>(ExecuteRemoveFunctionCommand));
  219. private DelegateCommand _LoadedCommand;
  220. public DelegateCommand LoadedCommand =>
  221. _LoadedCommand ?? (_LoadedCommand = new DelegateCommand(ExecuteLoadedCommand));
  222. private DelegateCommand _AddStockFunctionCommand;
  223. public DelegateCommand AddStockFunctionCommand =>
  224. _AddStockFunctionCommand ?? (_AddStockFunctionCommand = new DelegateCommand(ExecuteAddStockFunctionCommand));
  225. private DelegateCommand<object> _RemoveStockFunctionCommand;
  226. public DelegateCommand<object> RemoveStockFunctionCommand =>
  227. _RemoveStockFunctionCommand ?? (_RemoveStockFunctionCommand = new DelegateCommand<object>(ExecuteRemoveStockFunctionCommand));
  228. private DelegateCommand _AddStockFeederFunctionCommand;
  229. public DelegateCommand AddStockFeederFunctionCommand =>
  230. _AddStockFeederFunctionCommand ?? (_AddStockFeederFunctionCommand = new DelegateCommand(ExecuteAddStockFeederFunctionCommand));
  231. private DelegateCommand<object> _RemoveStockFeederFunctionCommand;
  232. public DelegateCommand<object> RemoveStockFeederFunctionCommand =>
  233. _RemoveStockFeederFunctionCommand ?? (_RemoveStockFeederFunctionCommand = new DelegateCommand<object>(ExecuteRemoveStockFeederFunctionCommand));
  234. private DelegateCommand _SettingStockCommand;
  235. public DelegateCommand SettingStockCommand =>
  236. _SettingStockCommand ?? (_SettingStockCommand = new DelegateCommand(ExecuteSettingStockCommand));
  237. private DelegateCommand<string> _RunCommandWorks;
  238. public DelegateCommand<string> RunCommandWorks =>
  239. _RunCommandWorks ?? (_RunCommandWorks = new DelegateCommand<string>(ExecuteRunCommandWorks).ObservesCanExecute(() => IsCanExecute));
  240. private DelegateCommand _AutoFindVibrationParamsCommand;
  241. public DelegateCommand AutoFindVibrationParamsCommand =>
  242. _AutoFindVibrationParamsCommand ?? (_AutoFindVibrationParamsCommand = new DelegateCommand(ExecuteAutoFindVibrationParamsCommand, CanExecuteAutoFindVibrationParamsCommand).ObservesProperty(() => InExecutionFindVibP));
  243. private DelegateCommand _StopAutoFindCommand;
  244. public DelegateCommand StopAutoFindCommand =>
  245. _StopAutoFindCommand ?? (_StopAutoFindCommand = new DelegateCommand(ExecuteStopAutoFindCommand, CanExecuteStopAutoFindCommand).ObservesProperty(() => InExecutionFindVibP));
  246. #endregion
  247. #region 事件
  248. #endregion
  249. public FeederParamsViewModel(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IDialogService dialogService)
  250. {
  251. _regionManager = regionManager;
  252. _eventAggregator = ea;
  253. _container = container;
  254. _dialogService = dialogService;
  255. //订阅权限登录事件
  256. _eventAggregator.GetEvent<UserLoginNotification>().Subscribe(LoginChange);
  257. management = _container.Resolve<Management>();
  258. productsViewModel = _container.Resolve<ProductsViewModel>();
  259. SelectProduct = productsViewModel.SelectProduct;
  260. SelectProcedure = _container.Resolve<ProcessBasicsViewModel>().SelectProcedure;
  261. }
  262. #region 方法
  263. /// <summary>
  264. /// 下一步
  265. /// </summary>
  266. async void ExecuteNextCommand()
  267. {
  268. _regionManager.RequestNavigate("ProductRegionContext", "ProcedureVisionOutput");
  269. try
  270. {
  271. if (Feeder != null && Feeder.IsConnected)
  272. {
  273. foreach (var item in SelectProcedure.FeederWorks.FeederWorkList)
  274. {
  275. if (item.Function == VibrationFunction.Delay) continue;
  276. var paramCollection = await Feeder.GetShakeGroupValueAsync((int)item.Function);
  277. item.SingleAction = paramCollection;
  278. }
  279. foreach (var item in SelectProcedure.FeederStockWorks.FeederWorkList)
  280. {
  281. if (item.Function == VibrationFunction.Delay) continue;
  282. var paramCollection = await Feeder.GetShakeGroupValueAsync((int)item.Function);
  283. item.SingleAction = paramCollection;
  284. }
  285. }
  286. }
  287. catch (Exception ex)
  288. {
  289. LogHelper.WriteLogError("Feeder 参数界面点击下一步时出错!", ex);
  290. MessageBox.Show(ex.Message);
  291. }
  292. }
  293. /// <summary>
  294. /// 上一步
  295. /// </summary>
  296. void ExecuteBackCommand()
  297. {
  298. if (SelectProcedure.VisionModel == Enums.VisionModel.Simple)
  299. {
  300. _regionManager.RequestNavigate("ProductRegionContext", "SimpleProcedure");
  301. }
  302. else
  303. {
  304. _regionManager.RequestNavigate("ProductRegionContext", "AdvancedProcedure");
  305. }
  306. }
  307. /// <summary>
  308. /// 增加振动盘振动任务
  309. /// </summary>
  310. async void ExecuteAddFunctionCommand()
  311. {
  312. try
  313. {
  314. if (SelectProcedure.FeederWorks == null)
  315. {
  316. SelectProcedure.FeederWorks = new FeederWorks();
  317. }
  318. if (SelectFeederFunction == VibrationFunction.Delay)
  319. {
  320. var view = new AddProduct() { Title = $"{Lang.添加动作}:", Item = $"{Lang.持续时长}(ms)" };
  321. //show the dialog
  322. var result = await DialogHost.Show(view, "RootDialog", null, null, null);
  323. if (result != null && !string.IsNullOrEmpty(result.ToString()) && int.TryParse(result.ToString(), out int time))
  324. {
  325. SelectProcedure.FeederWorks.Add(new FeederWork() { Step = SelectProcedure.FeederWorks.Count, Function = SelectFeederFunction, Duration = time });
  326. }
  327. }
  328. else
  329. {
  330. var view = new AddProduct() { Title = $"{Lang.添加动作}:", Item = $"{Lang.持续时长}(ms)" };
  331. //show the dialog
  332. var result = await DialogHost.Show(view, "RootDialog", null, null, null);
  333. if (result != null && !string.IsNullOrEmpty(result.ToString()) && int.TryParse(result.ToString(), out int time))
  334. {
  335. if (Feeder != null && Feeder.IsConnected)
  336. {
  337. var paramCollection = await Feeder.GetShakeGroupValueAsync((int)SelectFeederFunction);
  338. SelectProcedure.FeederWorks.Add(new FeederWork() { Step = SelectProcedure.FeederWorks.Count, Function = SelectFeederFunction, Duration = time, SingleAction = paramCollection });
  339. }
  340. else
  341. {
  342. SelectProcedure.FeederWorks.Add(new FeederWork() { Step = SelectProcedure.FeederWorks.Count, Function = SelectFeederFunction, Duration = time });
  343. }
  344. }
  345. }
  346. }
  347. catch (Exception ex)
  348. {
  349. LogHelper.WriteLogError("Feeder 参数界面增加振动盘任务时出错!", ex);
  350. MessageBox.Show(ex.Message);
  351. }
  352. }
  353. /// <summary>
  354. /// 移除振动盘振动任务
  355. /// </summary>
  356. /// <param name="index"></param>
  357. void ExecuteRemoveFunctionCommand(object index)
  358. {
  359. try
  360. {
  361. if (SelectProcedure.FeederWorks == null || SelectProcedure.FeederWorks.FeederWorkList == null)
  362. {
  363. return;
  364. }
  365. if ((int)index < 0) return;
  366. SelectProcedure.FeederWorks.FeederWorkList.RemoveAt((int)index);
  367. }
  368. catch (Exception ex)
  369. {
  370. LogHelper.WriteLogError("Feeder 参数界面移除振动盘任务时出错!", ex);
  371. MessageBox.Show(ex.Message);
  372. }
  373. }
  374. /// <summary>
  375. /// 增加料仓振动任务
  376. /// </summary>
  377. async void ExecuteAddStockFunctionCommand()
  378. {
  379. try
  380. {
  381. if (SelectProcedure.FeederStockWorks == null)
  382. {
  383. SelectProcedure.FeederStockWorks = new FeederStockWorks();
  384. SelectProcedure.FeederStockWorks.FeederStockWorkList = new ObservableCollection<FeederStockWork>();
  385. SelectProcedure.FeederStockWorks.FeederWorkList = new ObservableCollection<FeederWork>();
  386. }
  387. if (SelectProcedure.FeederStockWorks.FeederStockWorkList == null)
  388. {
  389. SelectProcedure.FeederStockWorks.FeederStockWorkList = new ObservableCollection<FeederStockWork>();
  390. }
  391. if (SelectProcedure.FeederStockWorks.FeederWorkList == null)
  392. {
  393. SelectProcedure.FeederStockWorks.FeederWorkList = new ObservableCollection<FeederWork>();
  394. }
  395. var view = new AddProduct() { Title = $"{Lang.添加动作}:", Item = $"{Lang.持续时长}(ms)" };
  396. //show the dialog
  397. var result = await DialogHost.Show(view, "RootDialog", null, null, null);
  398. if (result != null && !string.IsNullOrEmpty(result.ToString()) && int.TryParse(result.ToString(), out int time))
  399. {
  400. SelectProcedure.FeederStockWorks.FeederStockWorkList.Add(new FeederStockWork() { Step = SelectProcedure.FeederStockWorks.FeederStockWorkList.Count, Function = SelectStockFeederFunction, Duration = time });
  401. }
  402. }
  403. catch (Exception ex)
  404. {
  405. LogHelper.WriteLogError("Feeder 参数界面增加料仓任务时出错!", ex);
  406. MessageBox.Show(ex.Message);
  407. }
  408. }
  409. /// <summary>
  410. /// 移除料仓振动任务
  411. /// </summary>
  412. /// <param name="index"></param>
  413. void ExecuteRemoveStockFunctionCommand(object index)
  414. {
  415. try
  416. {
  417. if (SelectProcedure.FeederStockWorks == null || SelectProcedure.FeederStockWorks.FeederStockWorkList == null)
  418. {
  419. return;
  420. }
  421. if ((int)index < 0) return;
  422. SelectProcedure.FeederStockWorks.FeederStockWorkList.RemoveAt((int)index);
  423. }
  424. catch (Exception ex)
  425. {
  426. LogHelper.WriteLogError("Feeder 参数界面移除料仓任务时出错!", ex);
  427. MessageBox.Show(ex.Message);
  428. }
  429. }
  430. /// <summary>
  431. /// 增加料仓振动时的振动盘振动任务
  432. /// </summary>
  433. async void ExecuteAddStockFeederFunctionCommand()
  434. {
  435. try
  436. {
  437. if (SelectProcedure.FeederStockWorks == null)
  438. {
  439. SelectProcedure.FeederStockWorks = new FeederStockWorks();
  440. SelectProcedure.FeederStockWorks.FeederStockWorkList = new ObservableCollection<FeederStockWork>();
  441. SelectProcedure.FeederStockWorks.FeederWorkList = new ObservableCollection<FeederWork>();
  442. }
  443. if (SelectProcedure.FeederStockWorks.FeederStockWorkList == null)
  444. {
  445. SelectProcedure.FeederStockWorks.FeederStockWorkList = new ObservableCollection<FeederStockWork>();
  446. }
  447. if (SelectProcedure.FeederStockWorks.FeederWorkList == null)
  448. {
  449. SelectProcedure.FeederStockWorks.FeederWorkList = new ObservableCollection<FeederWork>();
  450. }
  451. if (SelectStockFeederFunction == VibrationFunction.Delay)
  452. {
  453. var view = new AddProduct() { Title = $"{Lang.添加动作}:", Item = $"{Lang.持续时长}(ms)" };
  454. //show the dialog
  455. var result = await DialogHost.Show(view, "RootDialog", null, null, null);
  456. if (result != null && !string.IsNullOrEmpty(result.ToString()) && int.TryParse(result.ToString(), out int time))
  457. {
  458. SelectProcedure.FeederStockWorks.FeederWorkList.Add(new FeederWork() { Step = SelectProcedure.FeederStockWorks.FeederWorkList.Count, Function = SelectStockFeederFunction, Duration = time });
  459. }
  460. }
  461. else
  462. {
  463. var view = new AddProduct() { Title = $"{Lang.添加动作}:", Item = $"{Lang.持续时长}(ms)" };
  464. //show the dialog
  465. var result = await DialogHost.Show(view, "RootDialog", null, null, null);
  466. if (result != null && !string.IsNullOrEmpty(result.ToString()) && int.TryParse(result.ToString(), out int time))
  467. {
  468. if (Feeder != null && Feeder.IsConnected)
  469. {
  470. var paramCollection = await Feeder.GetShakeGroupValueAsync((int)SelectStockFeederFunction);
  471. SelectProcedure.FeederStockWorks.FeederWorkList.Add(new FeederWork() { Step = SelectProcedure.FeederStockWorks.FeederWorkList.Count, Function = SelectStockFeederFunction, Duration = time, SingleAction = paramCollection });
  472. }
  473. else
  474. {
  475. SelectProcedure.FeederStockWorks.FeederWorkList.Add(new FeederWork() { Step = SelectProcedure.FeederStockWorks.FeederWorkList.Count, Function = SelectStockFeederFunction, Duration = time });
  476. }
  477. }
  478. }
  479. }
  480. catch (Exception ex)
  481. {
  482. LogHelper.WriteLogError("Feeder 参数界面增加料仓动作时的振动盘任务时出错!", ex);
  483. MessageBox.Show(ex.Message);
  484. }
  485. }
  486. /// <summary>
  487. /// 移除料仓振动任务
  488. /// </summary>
  489. /// <param name="index"></param>
  490. void ExecuteRemoveStockFeederFunctionCommand(object index)
  491. {
  492. try
  493. {
  494. if (SelectProcedure.FeederStockWorks == null || SelectProcedure.FeederStockWorks.FeederWorkList == null)
  495. {
  496. return;
  497. }
  498. if ((int)index < 0) return;
  499. SelectProcedure.FeederStockWorks.FeederWorkList.RemoveAt((int)index);
  500. }
  501. catch (Exception ex)
  502. {
  503. LogHelper.WriteLogError("Feeder 参数界面移除料仓动作时的振动盘任务时出错!", ex);
  504. MessageBox.Show(ex.Message);
  505. }
  506. }
  507. /// <summary>
  508. /// 料仓出料时机参数设定
  509. /// </summary>
  510. void ExecuteSettingStockCommand()
  511. {
  512. try
  513. {
  514. _dialogService.Show("FeederBlobParams", rst =>
  515. {
  516. //对话框关闭之后的回调函数,可以在这解析结果。
  517. ButtonResult result1 = rst.Result;
  518. if (result1 == ButtonResult.OK)
  519. {
  520. SelectProcedure.MinArea = rst.Parameters.GetValue<double>("MinArea");
  521. _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 1 });
  522. }
  523. });
  524. }
  525. catch (Exception ex)
  526. {
  527. LogHelper.WriteLogError("Feeder 参数界面打开FeederBlob参数界面时出错!", ex);
  528. MessageBox.Show(ex.Message);
  529. }
  530. }
  531. async void ExecuteLoadedCommand()
  532. {
  533. if (_container.Resolve<Management>().CurrentUser.userPart == Enums.UserPart.Operator)
  534. {
  535. IsAllowEdit = false;
  536. }
  537. else
  538. {
  539. IsAllowEdit = true;
  540. }
  541. try
  542. {
  543. productsViewModel = _container.Resolve<ProductsViewModel>();
  544. SelectProduct = productsViewModel.SelectProduct;
  545. SelectProcedure = _container.Resolve<ProcessBasicsViewModel>().SelectProcedure;
  546. feederService = management.FeederService;
  547. Feeder = feederService.GetFeeder(SelectProcedure.FeederId);
  548. if (Feeder != null && Feeder.IsConnected)
  549. {
  550. if (SelectProcedure.FeederWorks != null && SelectProcedure.FeederWorks.FeederWorkList != null)
  551. {
  552. foreach (var item in SelectProcedure.FeederWorks.FeederWorkList)
  553. {
  554. if (item.Function == VibrationFunction.Delay) continue;
  555. if (item.SingleAction == null) continue;
  556. await Feeder.SetShakeParametersAsync((int)item.Function, item.SingleAction);
  557. }
  558. }
  559. if (SelectProcedure.FeederStockWorks != null && SelectProcedure.FeederStockWorks.FeederWorkList != null)
  560. {
  561. foreach (var item in SelectProcedure.FeederStockWorks.FeederWorkList)
  562. {
  563. if (item.Function == VibrationFunction.Delay) continue;
  564. if (item.SingleAction == null) continue;
  565. await Feeder.SetShakeParametersAsync((int)item.Function, item.SingleAction);
  566. }
  567. }
  568. }
  569. if (SelectProcedure.FeederFindFrequency == null)
  570. {
  571. SelectProcedure.FeederFindFrequency = new FeederFrequencyModel(11);
  572. }
  573. if (SelectActionIndex < 0)
  574. {
  575. SelectActionIndex = 0;
  576. }
  577. if (SelectedActionParam.AmplitudeMax == SelectedActionParam.AmplitudeMin || SelectedActionParam.FrequencyMax == SelectedActionParam.FrequencyMin)
  578. {
  579. AutoAdjustmentParameter findVirTask = new AutoAdjustmentParameter(Feeder, SelectedActionParam.ActionIndex, ExecuteVisualPhoto);
  580. var defultpar = findVirTask.detector.GetLogicParameters();
  581. SelectedActionParam.AmplitudeMax = defultpar.u16MaxAmp;
  582. SelectedActionParam.AmplitudeMin = defultpar.u16MinAmp;
  583. SelectedActionParam.FrequencyMax = defultpar.u16MaxFre;
  584. SelectedActionParam.FrequencyMin = defultpar.u16MinFre;
  585. SelectedActionParam.Duration = defultpar.u16Tim;
  586. findVirTask.Dispose();
  587. }
  588. if (SingleActionParam.Motor1 == null)
  589. {
  590. SingleActionParam.Motor1 = new VoiceMotorParam();
  591. }
  592. if (SingleActionParam.Motor2 == null)
  593. {
  594. SingleActionParam.Motor2 = new VoiceMotorParam();
  595. }
  596. if (SingleActionParam.Motor3 == null)
  597. {
  598. SingleActionParam.Motor3 = new VoiceMotorParam();
  599. }
  600. if (SingleActionParam.Motor4 == null)
  601. {
  602. SingleActionParam.Motor4 = new VoiceMotorParam();
  603. }
  604. }
  605. catch (Exception ex)
  606. {
  607. LogHelper.WriteLogError("Feeder 参数界面打开FeederBlob参数界面时出错!", ex);
  608. MessageBox.Show(ex.Message);
  609. }
  610. }
  611. private bool _IsCanExecute = true;
  612. public bool IsCanExecute
  613. {
  614. get { return _IsCanExecute; }
  615. set { SetProperty(ref _IsCanExecute, value); }
  616. }
  617. async void ExecuteRunCommandWorks(string index)
  618. {
  619. try
  620. {
  621. IsCanExecute = false;
  622. int num = int.Parse(index);
  623. if (num == 0)
  624. {
  625. TokenSource = new CancellationTokenSource();
  626. var view = new WaitingPage();
  627. //show the dialog
  628. DialogHost.Show(view, "RootDialog", null, ExtendedClosingEventHandler, ExtendedClosedEventHandler);
  629. await management.ExecuteFeederWorks(Feeder, SelectProcedure.FeederWorks, TokenSource.Token, false);
  630. if (DialogHost.IsDialogOpen("RootDialog"))
  631. {
  632. TokenSource = null;
  633. DialogHost.Close("RootDialog");
  634. }
  635. TokenSource = null;
  636. }
  637. else if (num == 1)
  638. {
  639. TokenSource = new CancellationTokenSource();
  640. var view = new WaitingPage();
  641. //show the dialog
  642. DialogHost.Show(view, "RootDialog", null, ExtendedClosingEventHandler, ExtendedClosedEventHandler);
  643. await management.ExecuteFeederStockWorks(Feeder, SelectProcedure.FeederStockWorks, TokenSource.Token, false);
  644. if (DialogHost.IsDialogOpen("RootDialog"))
  645. {
  646. TokenSource = null;
  647. DialogHost.Close("RootDialog");
  648. }
  649. TokenSource = null;
  650. }
  651. }
  652. catch (Exception ex)
  653. {
  654. LogHelper.WriteLogError("Feeder 参数界面执行Feeder运动任务时出错时出错!", ex);
  655. MessageBox.Show(ex.Message);
  656. }
  657. finally
  658. {
  659. IsCanExecute = true;
  660. }
  661. }
  662. private void ExtendedClosingEventHandler(object sender, DialogClosingEventArgs eventArgs)
  663. {
  664. if (TokenSource != null)
  665. {
  666. TokenSource.Cancel();
  667. }
  668. }
  669. private void ExtendedClosedEventHandler(object sender, DialogClosedEventArgs eventArgs)
  670. {
  671. }
  672. /// <summary>
  673. /// 自动寻频
  674. /// </summary>
  675. async void ExecuteAutoFindVibrationParamsCommand()
  676. {
  677. try
  678. {
  679. AutoFindVirCTS = new CancellationTokenSource();
  680. InExecutionFindVibP = true;
  681. var calib = management.DeviceConfig.Calibrations.FirstOrDefault(f => f.Id == SelectProcedure.CalibrationId);
  682. if (SelectedActionParam == null)
  683. {
  684. SelectedActionParam = new ActionParamsExtModel();
  685. }
  686. AutoAdjustmentParameter findVirTask = new AutoAdjustmentParameter(Feeder, SelectedActionParam.ActionIndex, ExecuteVisualPhoto);
  687. findVirTask.OnVibrationParamChanged += (amp) =>
  688. {
  689. Application.Current.Dispatcher.Invoke(() =>
  690. {
  691. SingleActionParam.Motor1.Amplitude = amp.Motor1.Amplitude;
  692. SingleActionParam.Motor1.Frequency = amp.Motor1.Frequency;
  693. SingleActionParam.Motor1.Phase = amp.Motor1.Phase;
  694. SingleActionParam.Motor1.WaveShape = amp.Motor1.WaveShape;
  695. SingleActionParam.Motor2.Amplitude = amp.Motor2.Amplitude;
  696. SingleActionParam.Motor2.Frequency = amp.Motor3.Frequency;
  697. SingleActionParam.Motor2.Phase = amp.Motor2.Phase;
  698. SingleActionParam.Motor2.WaveShape = amp.Motor2.WaveShape;
  699. SingleActionParam.Motor3.Amplitude = amp.Motor3.Amplitude;
  700. SingleActionParam.Motor3.Frequency = amp.Motor3.Frequency;
  701. SingleActionParam.Motor3.Phase = amp.Motor3.Phase;
  702. SingleActionParam.Motor3.WaveShape = amp.Motor3.WaveShape;
  703. SingleActionParam.Motor4.Amplitude = amp.Motor4.Amplitude;
  704. SingleActionParam.Motor4.Frequency = amp.Motor4.Frequency;
  705. SingleActionParam.Motor4.Phase = amp.Motor4.Phase;
  706. SingleActionParam.Motor4.WaveShape = amp.Motor4.WaveShape;
  707. SingleActionParam.DurationValue = amp.DurationValue;
  708. });
  709. };
  710. findVirTask.detector.SetLogicParameters((ushort)SelectedActionParam.AmplitudeMin, (ushort)SelectedActionParam.AmplitudeMax, (ushort)SelectedActionParam.FrequencyMin, (ushort)SelectedActionParam.FrequencyMax, (ushort)SelectedActionParam.Duration);
  711. await findVirTask.Execute(SelectedActionParam.AmplitudeMax, SelectedActionParam.AmplitudeMin, SelectedActionParam.FrequencyMax, SelectedActionParam.FrequencyMin, SelectedActionParam.Duration, AutoFindVirCTS.Token, res =>
  712. {
  713. //0 :失败 1:运行中 3:完成调频 6:验证结束
  714. if (res == 0)
  715. {
  716. App.Current.Dispatcher.Invoke(() =>
  717. {
  718. StateMesg = "寻频失败";
  719. });
  720. AutoFindVirCTS.Cancel();
  721. }
  722. else if (res == 1)
  723. {
  724. App.Current.Dispatcher.Invoke(() =>
  725. {
  726. StateMesg = "寻频中...";
  727. });
  728. }
  729. //动作结束
  730. else if (res == 2)
  731. {
  732. App.Current.Dispatcher.Invoke(() =>
  733. {
  734. StateMesg = "移动物料到起始位置";
  735. });
  736. //if (MessageBox.Show( "请将物料手动移动回原位,将进行下一次调频。", "AAS", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes)
  737. //{
  738. // //findVirTask.SetState(1);
  739. //}
  740. //else
  741. //{
  742. // //AutoFindVirCTS.Cancel();
  743. //}
  744. }
  745. //完成调频,进行测试效果
  746. else if (res == 3)
  747. {
  748. App.Current.Dispatcher.Invoke(() =>
  749. {
  750. StateMesg = "验证进行中";
  751. });
  752. if (MessageBox.Show("请使用更多物料去验证动作振动效果。", "AAS", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes)
  753. {
  754. findVirTask.SetState(2);
  755. }
  756. else
  757. {
  758. App.Current.Dispatcher.Invoke(() =>
  759. {
  760. StateMesg = "停止";
  761. });
  762. findVirTask.SetState(0);
  763. AutoFindVirCTS.Cancel();
  764. }
  765. }
  766. //验证结束。
  767. else if (res == 6)
  768. {
  769. App.Current.Dispatcher.Invoke(() =>
  770. {
  771. StateMesg = "验证结束";
  772. });
  773. if (MessageBox.Show("是否重复震动验证?", "AAS", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes)
  774. {
  775. App.Current.Dispatcher.Invoke(() =>
  776. {
  777. StateMesg = "重复验证";
  778. });
  779. findVirTask.SetState(2);
  780. }
  781. else
  782. {
  783. if (MessageBox.Show("请确认当前振动效果是否正确?", "AAS", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes)
  784. {
  785. App.Current.Dispatcher.Invoke(() =>
  786. {
  787. StateMesg = "验证完成";
  788. });
  789. findVirTask.SetState(3);
  790. AutoFindVirCTS.Cancel();
  791. }
  792. else
  793. {
  794. App.Current.Dispatcher.Invoke(() =>
  795. {
  796. StateMesg = "继续调频";
  797. });
  798. findVirTask.SetState(1);
  799. //AutoFindVirCTS.Cancel();
  800. }
  801. }
  802. }
  803. });
  804. findVirTask.Dispose();
  805. Feeder.CloseLight();
  806. }
  807. catch (Exception ex)
  808. {
  809. LogHelper.WriteLogError("Feeder 参数界面执行自动寻找振动参数时出错!", ex);
  810. }
  811. finally
  812. {
  813. InExecutionFindVibP = false;
  814. }
  815. }
  816. bool CanExecuteAutoFindVibrationParamsCommand()
  817. {
  818. return !InExecutionFindVibP;
  819. }
  820. /// <summary>
  821. /// 停止自动寻找振动参数
  822. /// </summary>
  823. void ExecuteStopAutoFindCommand()
  824. {
  825. if (AutoFindVirCTS != null)
  826. {
  827. AutoFindVirCTS.Cancel();
  828. }
  829. }
  830. bool CanExecuteStopAutoFindCommand()
  831. {
  832. return InExecutionFindVibP;
  833. }
  834. /// <summary>
  835. /// 执行相机拍照(拍摄Feeder,自动寻频功能),并返回拍照结果
  836. /// </summary>
  837. /// <returns></returns>
  838. private Tuple<bool, float, float> ExecuteVisualPhoto()
  839. {
  840. try
  841. {
  842. if (!Feeder.QueryLightState())
  843. {
  844. Feeder.OpenLight();
  845. Thread.Sleep(100);
  846. }
  847. var cam = management.CameraService.GetCamera(SelectProcedure.CameraId);
  848. if (!SelectProcedure.ToolBlock.Tools.Contains("CogToolBlock-FeederCalib"))
  849. {
  850. ShowMsg("视觉工具组不存在名称为:'CogToolBlock-FeederCalib'的ToolBlock");
  851. return new Tuple<bool, float, float>(false, 0, 0);
  852. }
  853. var tb = SelectProcedure.ToolBlock.Tools["CogToolBlock-FeederCalib"] as CogToolBlock;
  854. var image = cam.Grab();
  855. tb.Inputs["InputImage"].Value = image;
  856. tb.Run();
  857. Mat mat = ICogImageConvertMat(image);
  858. if (tb.RunStatus.Result != CogToolResultConstants.Accept)
  859. {
  860. CameraImage = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToBitmapSource(mat);
  861. mat.Dispose();
  862. ShowMsg($"CogToolBlock-FeederCalib运行出错!error:{tb.RunStatus.Message}");
  863. LogHelper.WriteLogInfo($"CogToolBlock-FeederCalib运行出错!error:{tb.RunStatus.Message}");
  864. return new Tuple<bool, float, float>(false, 0, 0);
  865. }
  866. bool found = (bool)tb.Outputs["Found"].Value;
  867. if (!found)
  868. {
  869. CameraImage = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToBitmapSource(mat);
  870. mat.Dispose();
  871. ShowMsg($"视觉工具运行失败!");
  872. return new Tuple<bool, float, float>(false, 0, 0);
  873. }
  874. CogRectangleAffine Rectangle = tb.Outputs["Rectang"].Value as CogRectangleAffine;
  875. double MassX = (double)tb.Outputs["MassX"].Value;
  876. double MassY = (double)tb.Outputs["MassY"].Value;
  877. //创建旋转矩形对象
  878. OpenCvSharp.RotatedRect rotatedRect = new OpenCvSharp.RotatedRect(new OpenCvSharp.Point2f((float)Rectangle.CenterX, (float)Rectangle.CenterY), new OpenCvSharp.Size2f((float)Rectangle.SideXLength, (float)Rectangle.SideYLength), (float)ToolCoord.RadToAngle(Rectangle.Rotation));
  879. // 获取矩形的四个顶点
  880. Point2f[] vertices = rotatedRect.Points();
  881. //[1]━━━━━━━━━━[2]
  882. // ┃ ┃
  883. // ┃ ┃
  884. // ┃ ┃
  885. //[0]━━━━━━━━━━[3]
  886. // 绘制旋转矩形
  887. Cv2.DrawContours(mat, new[] { Array.ConvertAll(vertices, v => new OpenCvSharp.Point((int)v.X, (int)v.Y)) }, 0, Scalar.Blue, 2);
  888. // 绘制标记点
  889. Cv2.DrawMarker(mat, new OpenCvSharp.Point(MassX, MassY),
  890. new Scalar(255, 0, 0), MarkerTypes.Cross, 40, 5);
  891. //绘制Feeder坐标系
  892. if (!SelectProcedure.FeederFindFrequency.FeederDirectionInverse)
  893. {
  894. Cv2.Line(mat, (int)vertices[2].X, (int)vertices[2].Y, (int)vertices[1].X, (int)vertices[1].Y, Scalar.Red, 5);
  895. Cv2.Line(mat, (int)vertices[2].X, (int)vertices[2].Y, (int)vertices[3].X, (int)vertices[3].Y, Scalar.Green, 5);
  896. }
  897. else
  898. {
  899. Cv2.Line(mat, (int)vertices[0].X, (int)vertices[0].Y, (int)vertices[3].X, (int)vertices[3].Y, Scalar.Red, 5);
  900. Cv2.Line(mat, (int)vertices[0].X, (int)vertices[0].Y, (int)vertices[1].X, (int)vertices[1].Y, Scalar.Green, 5);
  901. }
  902. App.Current.Dispatcher.Invoke(() =>
  903. {
  904. CameraImage = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToBitmapSource(mat);
  905. });
  906. mat.Dispose();
  907. var calib = management.DeviceConfig.Calibrations.FirstOrDefault(f => f.Id == SelectProcedure.CalibrationId);
  908. Point2f p0 = new Point2f((float)(MassX * calib.PixelScaleX), (float)(MassY * calib.PixelScaleY));
  909. //矩形顶点坐标(mm)
  910. Point2f p1 = new Point2f((float)(vertices[0].X * calib.PixelScaleX + 10), (float)(vertices[0].Y * calib.PixelScaleY));
  911. Point2f p2 = new Point2f((float)(vertices[1].X * calib.PixelScaleX + 10), (float)(vertices[1].Y * calib.PixelScaleY));
  912. Point2f p3 = new Point2f((float)(vertices[2].X * calib.PixelScaleX + 10), (float)(vertices[2].Y * calib.PixelScaleY));
  913. Point2f p4 = new Point2f((float)(vertices[3].X * calib.PixelScaleX + 10), (float)(vertices[3].Y * calib.PixelScaleY));
  914. //创建Local坐标系
  915. CoordinateTransformer local = new CoordinateTransformer(p3.X, p3.Y, p2.X, p2.Y, p4.X, p4.Y);
  916. if (SelectProcedure.FeederFindFrequency.FeederDirectionInverse)
  917. {
  918. local = new CoordinateTransformer(p1.X, p1.Y, p4.X, p4.Y, p2.X, p2.Y);
  919. }
  920. //转换到Local坐标系
  921. Vector<double> localP = local.ToNewCoord(p0.X, p0.Y);
  922. return new Tuple<bool, float, float>(found, (float)localP[0], (float)localP[1]);
  923. }
  924. catch (Exception ex)
  925. {
  926. LogHelper.WriteLogError("执行相机拍照(拍摄Feeder,自动寻频功能)时出错!", ex);
  927. return new Tuple<bool, float, float>(false, 0, 0);
  928. }
  929. }
  930. private Mat ICogImageConvertMat(ICogImage image)
  931. {
  932. var im = image.ToBitmap();
  933. Mat im1 = OpenCvSharp.Extensions.BitmapConverter.ToMat(im);
  934. im.Dispose();
  935. return im1;
  936. }
  937. #endregion
  938. private void ShowMsg(string msg, double duration = 1)
  939. {
  940. //_eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = msg, Duration = duration });
  941. }
  942. private bool _IsAllowEdit = false;
  943. public bool IsAllowEdit
  944. {
  945. get { return _IsAllowEdit; }
  946. set { SetProperty(ref _IsAllowEdit, value); }
  947. }
  948. private void LoginChange(Models.User user)
  949. {
  950. if (user.userPart == Enums.UserPart.Operator)
  951. {
  952. IsAllowEdit = false;
  953. }
  954. else
  955. {
  956. IsAllowEdit = true;
  957. }
  958. }
  959. }
  960. }