FeederParamsViewModel.cs 47 KB

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