CalibIndependentCameraViewModel.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. using Cognex.VisionPro;
  2. using Cognex.VisionPro.ToolBlock;
  3. using MathNet.Numerics.LinearAlgebra;
  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.Linq;
  13. using System.Threading;
  14. using System.Threading.Tasks;
  15. using System.Windows;
  16. using Team.FFFeederService.Interfaces;
  17. using TeamAAS_VP.Core;
  18. using TeamAAS_VP.Interfaces;
  19. using TeamAAS_VP.Models.Calibration;
  20. using TeamAAS_VP.Models.Robot;
  21. using TeamAAS_VP.Resources.Languages;
  22. namespace TeamAAS_VP.ViewModels.Calibration
  23. {
  24. public class CalibIndependentCameraViewModel : BindableBase, IConfirmNavigationRequest
  25. {
  26. IRegionManager _regionManager;
  27. IRegionNavigationService _regionNavigationService;
  28. IContainerProvider _container;
  29. IDialogService _dialogService;
  30. IEventAggregator _eventAggregator;
  31. IRobotService _robotService;
  32. IFeederService _feederService;
  33. ICameraService _cameraService;
  34. ISystemDatabaseService _systemDatabaseService;
  35. ICameraCalibrationService _cameraCalibrationService;
  36. private CancellationTokenSource _cts;
  37. #region 属性
  38. private ICogImage _Image;
  39. public ICogImage Image
  40. {
  41. get { return _Image; }
  42. set { SetProperty(ref _Image, value); }
  43. }
  44. private Cognex.VisionPro.CogGraphicCollection _Graphic;
  45. public Cognex.VisionPro.CogGraphicCollection Graphic
  46. {
  47. get { return _Graphic; }
  48. set { SetProperty(ref _Graphic, value); }
  49. }
  50. private CalibrationInfo _SelectCalibration;
  51. public CalibrationInfo SelectCalibration
  52. {
  53. get { return _SelectCalibration; }
  54. set { SetProperty(ref _SelectCalibration, value); }
  55. }
  56. public Management management { get; set; }
  57. public IRobot Robot { get; set; }
  58. private bool _IsRunning = true;
  59. public bool IsRunning
  60. {
  61. get { return _IsRunning; }
  62. set { SetProperty(ref _IsRunning, value); }
  63. }
  64. private ICamera _Camera;
  65. public ICamera Camera
  66. {
  67. get { return _Camera; }
  68. set { SetProperty(ref _Camera, value); }
  69. }
  70. #endregion
  71. #region 命令
  72. private DelegateCommand _NextCommand;
  73. public DelegateCommand NextCommand =>
  74. _NextCommand ?? (_NextCommand = new DelegateCommand(ExecuteNextCommand).ObservesCanExecute(() => IsRunning));
  75. private DelegateCommand _BackCommand;
  76. public DelegateCommand BackCommand =>
  77. _BackCommand ?? (_BackCommand = new DelegateCommand(ExecuteBackCommand).ObservesCanExecute(() => IsRunning));
  78. private DelegateCommand _StartCalibCommand;
  79. public DelegateCommand StartCalibCommand =>
  80. _StartCalibCommand ?? (_StartCalibCommand = new DelegateCommand(ExecuteStartCalibCommand).ObservesCanExecute(() => IsRunning));
  81. #endregion
  82. #region 事件
  83. #endregion
  84. public CalibIndependentCameraViewModel(IRegionManager regionManager, IEventAggregator ea, IRegionNavigationService regionNavigationService, IContainerProvider container, IDialogService dialogService,
  85. IRobotService robotService, IFeederService feederService, ICameraService cameraService, ISystemDatabaseService systemDatabaseService, ICameraCalibrationService cameraCalibrationService)
  86. {
  87. _regionManager = regionManager;
  88. _regionNavigationService = regionNavigationService;
  89. _container = container;
  90. _dialogService = dialogService;
  91. _robotService = robotService;
  92. _eventAggregator = ea;
  93. _feederService = feederService;
  94. _cameraService = cameraService;
  95. _systemDatabaseService = systemDatabaseService;
  96. _cameraCalibrationService = cameraCalibrationService;
  97. }
  98. #region 方法
  99. async void ExecuteStartCalibCommand()
  100. {
  101. try
  102. {
  103. //弹窗提示是否开始独立移动相机刚体变换校准
  104. MessageBoxResult msgResult = MessageBox.Show("是否开始独立移动相机位置校准", Lang.自动校准, MessageBoxButton.YesNo, MessageBoxImage.Question);
  105. if (msgResult != MessageBoxResult.Yes)
  106. {
  107. return;
  108. }
  109. IsRunning = false;
  110. _cts = new CancellationTokenSource();
  111. (bool IsSuccess, double[,] TransformationMatrix) = await _cameraCalibrationService.CalculateIndependentCameraRigidTransformationMatrix(SelectCalibration, Robot, _cts.Token);
  112. if (!IsSuccess)
  113. {
  114. MessageBox.Show("独立移动相机位置校准失败", $"{Lang.自动校准}", MessageBoxButton.OK, MessageBoxImage.Warning);
  115. return;
  116. }
  117. SelectCalibration.IndependentDownCameraMotionModuleHomogeneousMatrix = TransformationMatrix;
  118. NavigationParameters param = new NavigationParameters();
  119. param.Add("SelectCalibration", SelectCalibration);
  120. _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
  121. }
  122. catch (Exception ex)
  123. {
  124. LogHelper.WriteLogError("独立移动相机位置校准时出错!", ex);
  125. MessageBox.Show(ex.Message);
  126. }
  127. finally
  128. {
  129. try
  130. {
  131. if (_cts != null && !_cts.IsCancellationRequested)
  132. _cts.Cancel();
  133. _cts?.Dispose();
  134. _cts = null;
  135. }
  136. catch (Exception)
  137. {
  138. }
  139. IsRunning = true;
  140. }
  141. }
  142. /// <summary>
  143. /// 下一步
  144. /// </summary>
  145. void ExecuteNextCommand()
  146. {
  147. NavigationParameters param = new NavigationParameters();
  148. param.Add("SelectCalibration", SelectCalibration);
  149. _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
  150. }
  151. /// <summary>
  152. /// 上一步
  153. /// </summary>
  154. void ExecuteBackCommand()
  155. {
  156. NavigationParameters param = new NavigationParameters();
  157. param.Add("SelectCalibration", SelectCalibration);
  158. _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationSelectTool", param);
  159. }
  160. /// <summary>
  161. /// 相机拍照
  162. /// </summary>
  163. /// <returns></returns>
  164. private async Task<(bool IsSuccess, double X, double Y, double U, int ImageWidth, int ImageHeight)> CaptureAndProcess()
  165. {
  166. await Task.Delay(200);
  167. //采集图像
  168. if (Camera != null)
  169. {
  170. SelectCalibration.ToolBlock.Inputs["InputImage"].Value = Camera.Grab();
  171. }
  172. App.Current.Dispatcher.Invoke(() =>
  173. {
  174. Graphic = null;
  175. Image = (ICogImage)SelectCalibration.ToolBlock.Inputs["InputImage"].Value;
  176. });
  177. SelectCalibration.ToolBlock.Run();
  178. CogToolBlockTerminalCollection outputCollection = SelectCalibration.ToolBlock.Outputs;
  179. App.Current.Dispatcher.Invoke(() =>
  180. {
  181. Graphic = outputCollection["Graphic"].Value as CogGraphicCollection;
  182. });
  183. bool Found = (bool)(outputCollection["Found"].Value);
  184. if (Found)
  185. {
  186. var strpoints = outputCollection["Point"].Value.ToString();
  187. string[] items = strpoints.Split(',');
  188. double x = double.Parse(items[0]);
  189. double y = double.Parse(items[1]);
  190. return (true, x, y, 0, Image.Width, Image.Height);
  191. }
  192. else
  193. {
  194. return (false, 0, 0, 0, Image.Width, Image.Height);
  195. }
  196. }
  197. #endregion
  198. #region 继承
  199. /// <summary>
  200. /// 确认导航请求时调用。此方法允许您在导航之前执行一些操作。
  201. /// </summary>
  202. /// <param name="navigationContext"></param>
  203. /// <param name="continuationCallback"></param>
  204. public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
  205. {
  206. continuationCallback(true);
  207. }
  208. /// <summary>
  209. /// 接收导航请求时调用。传入导航参数,包含有关导航目标的信息。
  210. /// </summary>
  211. /// <param name="navigationContext"></param>
  212. /// <exception cref="NotImplementedException"></exception>
  213. public async void OnNavigatedTo(NavigationContext navigationContext)
  214. {
  215. SelectCalibration = navigationContext.Parameters.GetValue<CalibrationInfo>("SelectCalibration");
  216. if (SelectCalibration != null)
  217. {
  218. Robot = _robotService.GetRobot(SelectCalibration.RobotId);
  219. }
  220. Camera = _cameraService.GetCamera(SelectCalibration.CameraID);
  221. _cameraCalibrationService.CaptureAndProcessCallback = null;
  222. _cameraCalibrationService.CaptureAndProcessCallback = CaptureAndProcess;
  223. if (_systemDatabaseService.GetCurrentUser().userPart == Enums.UserPart.Operator)
  224. {
  225. IsAllowEdit = false;
  226. }
  227. else
  228. {
  229. IsAllowEdit = true;
  230. }
  231. }
  232. /// <summary>
  233. /// 是否允许导航到此视图模型。
  234. /// </summary>
  235. /// <param name="navigationContext"></param>
  236. /// <returns></returns>
  237. public bool IsNavigationTarget(NavigationContext navigationContext)
  238. {
  239. return true;
  240. }
  241. /// <summary>
  242. /// 导航离开此视图模型时调用。您可以在此处执行清理操作或保存状态。
  243. /// </summary>
  244. /// <param name="navigationContext"></param>
  245. public void OnNavigatedFrom(NavigationContext navigationContext)
  246. {
  247. _cameraCalibrationService.CaptureAndProcessCallback = null;
  248. }
  249. #endregion
  250. private bool _IsAllowEdit = false;
  251. public bool IsAllowEdit
  252. {
  253. get { return _IsAllowEdit; }
  254. set { SetProperty(ref _IsAllowEdit, value); }
  255. }
  256. private void LoginChange(Models.User user)
  257. {
  258. if (user.userPart == Enums.UserPart.Operator)
  259. {
  260. IsAllowEdit = false;
  261. }
  262. else
  263. {
  264. IsAllowEdit = true;
  265. }
  266. }
  267. }
  268. }