|
@@ -0,0 +1,306 @@
|
|
|
|
|
+using Cognex.VisionPro;
|
|
|
|
|
+using Cognex.VisionPro.ToolBlock;
|
|
|
|
|
+using MathNet.Numerics.LinearAlgebra;
|
|
|
|
|
+using Prism.Commands;
|
|
|
|
|
+using Prism.Events;
|
|
|
|
|
+using Prism.Ioc;
|
|
|
|
|
+using Prism.Mvvm;
|
|
|
|
|
+using Prism.Regions;
|
|
|
|
|
+using Prism.Services.Dialogs;
|
|
|
|
|
+using System;
|
|
|
|
|
+using System.Collections.Generic;
|
|
|
|
|
+using System.Linq;
|
|
|
|
|
+using System.Threading;
|
|
|
|
|
+using System.Threading.Tasks;
|
|
|
|
|
+using System.Windows;
|
|
|
|
|
+using Team.FFFeederService.Interfaces;
|
|
|
|
|
+using TeamAAS_VP.Core;
|
|
|
|
|
+using TeamAAS_VP.Interfaces;
|
|
|
|
|
+using TeamAAS_VP.Models.Calibration;
|
|
|
|
|
+using TeamAAS_VP.Models.Robot;
|
|
|
|
|
+using TeamAAS_VP.Resources.Languages;
|
|
|
|
|
+
|
|
|
|
|
+namespace TeamAAS_VP.ViewModels.Calibration
|
|
|
|
|
+{
|
|
|
|
|
+ public class CalibIndependentCameraViewModel : BindableBase, IConfirmNavigationRequest
|
|
|
|
|
+ {
|
|
|
|
|
+ IRegionManager _regionManager;
|
|
|
|
|
+ IRegionNavigationService _regionNavigationService;
|
|
|
|
|
+ IContainerProvider _container;
|
|
|
|
|
+ IDialogService _dialogService;
|
|
|
|
|
+ IEventAggregator _eventAggregator;
|
|
|
|
|
+ IRobotService _robotService;
|
|
|
|
|
+ IFeederService _feederService;
|
|
|
|
|
+ ICameraService _cameraService;
|
|
|
|
|
+ ISystemDatabaseService _systemDatabaseService;
|
|
|
|
|
+ ICameraCalibrationService _cameraCalibrationService;
|
|
|
|
|
+ private CancellationTokenSource _cts;
|
|
|
|
|
+ #region 属性
|
|
|
|
|
+ private ICogImage _Image;
|
|
|
|
|
+
|
|
|
|
|
+ public ICogImage Image
|
|
|
|
|
+ {
|
|
|
|
|
+ get { return _Image; }
|
|
|
|
|
+ set { SetProperty(ref _Image, value); }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private Cognex.VisionPro.CogGraphicCollection _Graphic;
|
|
|
|
|
+
|
|
|
|
|
+ public Cognex.VisionPro.CogGraphicCollection Graphic
|
|
|
|
|
+ {
|
|
|
|
|
+ get { return _Graphic; }
|
|
|
|
|
+ set { SetProperty(ref _Graphic, value); }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private CalibrationInfo _SelectCalibration;
|
|
|
|
|
+
|
|
|
|
|
+ public CalibrationInfo SelectCalibration
|
|
|
|
|
+ {
|
|
|
|
|
+ get { return _SelectCalibration; }
|
|
|
|
|
+ set { SetProperty(ref _SelectCalibration, value); }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public Management management { get; set; }
|
|
|
|
|
+ public IRobot Robot { get; set; }
|
|
|
|
|
+
|
|
|
|
|
+ private bool _IsRunning = true;
|
|
|
|
|
+
|
|
|
|
|
+ public bool IsRunning
|
|
|
|
|
+ {
|
|
|
|
|
+ get { return _IsRunning; }
|
|
|
|
|
+ set { SetProperty(ref _IsRunning, value); }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private ICamera _Camera;
|
|
|
|
|
+
|
|
|
|
|
+ public ICamera Camera
|
|
|
|
|
+ {
|
|
|
|
|
+ get { return _Camera; }
|
|
|
|
|
+ set { SetProperty(ref _Camera, value); }
|
|
|
|
|
+ }
|
|
|
|
|
+ #endregion
|
|
|
|
|
+
|
|
|
|
|
+ #region 命令
|
|
|
|
|
+ private DelegateCommand _NextCommand;
|
|
|
|
|
+ public DelegateCommand NextCommand =>
|
|
|
|
|
+ _NextCommand ?? (_NextCommand = new DelegateCommand(ExecuteNextCommand).ObservesCanExecute(() => IsRunning));
|
|
|
|
|
+
|
|
|
|
|
+ private DelegateCommand _BackCommand;
|
|
|
|
|
+ public DelegateCommand BackCommand =>
|
|
|
|
|
+ _BackCommand ?? (_BackCommand = new DelegateCommand(ExecuteBackCommand).ObservesCanExecute(() => IsRunning));
|
|
|
|
|
+
|
|
|
|
|
+ private DelegateCommand _StartCalibCommand;
|
|
|
|
|
+ public DelegateCommand StartCalibCommand =>
|
|
|
|
|
+ _StartCalibCommand ?? (_StartCalibCommand = new DelegateCommand(ExecuteStartCalibCommand).ObservesCanExecute(() => IsRunning));
|
|
|
|
|
+
|
|
|
|
|
+ #endregion
|
|
|
|
|
+
|
|
|
|
|
+ #region 事件
|
|
|
|
|
+
|
|
|
|
|
+ #endregion
|
|
|
|
|
+
|
|
|
|
|
+ public CalibIndependentCameraViewModel(IRegionManager regionManager, IEventAggregator ea, IRegionNavigationService regionNavigationService, IContainerProvider container, IDialogService dialogService,
|
|
|
|
|
+ IRobotService robotService, IFeederService feederService, ICameraService cameraService, ISystemDatabaseService systemDatabaseService, ICameraCalibrationService cameraCalibrationService)
|
|
|
|
|
+ {
|
|
|
|
|
+ _regionManager = regionManager;
|
|
|
|
|
+ _regionNavigationService = regionNavigationService;
|
|
|
|
|
+ _container = container;
|
|
|
|
|
+ _dialogService = dialogService;
|
|
|
|
|
+ _robotService = robotService;
|
|
|
|
|
+ _eventAggregator = ea;
|
|
|
|
|
+ _feederService = feederService;
|
|
|
|
|
+ _cameraService = cameraService;
|
|
|
|
|
+ _systemDatabaseService = systemDatabaseService;
|
|
|
|
|
+ _cameraCalibrationService = cameraCalibrationService;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #region 方法
|
|
|
|
|
+
|
|
|
|
|
+ async void ExecuteStartCalibCommand()
|
|
|
|
|
+ {
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ //弹窗提示是否开始独立移动相机刚体变换校准
|
|
|
|
|
+ MessageBoxResult msgResult = MessageBox.Show("是否开始独立移动相机位置校准", Lang.自动校准, MessageBoxButton.YesNo, MessageBoxImage.Question);
|
|
|
|
|
+ if (msgResult != MessageBoxResult.Yes)
|
|
|
|
|
+ {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ IsRunning = false;
|
|
|
|
|
+ _cts = new CancellationTokenSource();
|
|
|
|
|
+ (bool IsSuccess, double[,] TransformationMatrix) = await _cameraCalibrationService.CalculateIndependentCameraRigidTransformationMatrix(SelectCalibration, Robot, _cts.Token);
|
|
|
|
|
+ if (!IsSuccess)
|
|
|
|
|
+ {
|
|
|
|
|
+ MessageBox.Show("独立移动相机位置校准失败", $"{Lang.自动校准}", MessageBoxButton.OK, MessageBoxImage.Warning);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ SelectCalibration.IndependentDownCameraMotionModuleHomogeneousMatrix = TransformationMatrix;
|
|
|
|
|
+ NavigationParameters param = new NavigationParameters();
|
|
|
|
|
+ param.Add("SelectCalibration", SelectCalibration);
|
|
|
|
|
+ _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception ex)
|
|
|
|
|
+ {
|
|
|
|
|
+ LogHelper.WriteLogError("独立移动相机位置校准时出错!", ex);
|
|
|
|
|
+ MessageBox.Show(ex.Message);
|
|
|
|
|
+ }
|
|
|
|
|
+ finally
|
|
|
|
|
+ {
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ if (_cts != null && !_cts.IsCancellationRequested)
|
|
|
|
|
+ _cts.Cancel();
|
|
|
|
|
+ _cts?.Dispose();
|
|
|
|
|
+ _cts = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception)
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ IsRunning = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 下一步
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ void ExecuteNextCommand()
|
|
|
|
|
+ {
|
|
|
|
|
+ NavigationParameters param = new NavigationParameters();
|
|
|
|
|
+ param.Add("SelectCalibration", SelectCalibration);
|
|
|
|
|
+ _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationAuto", param);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 上一步
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ void ExecuteBackCommand()
|
|
|
|
|
+ {
|
|
|
|
|
+ NavigationParameters param = new NavigationParameters();
|
|
|
|
|
+ param.Add("SelectCalibration", SelectCalibration);
|
|
|
|
|
+
|
|
|
|
|
+ _regionManager.RequestNavigate("CalibrationRegionContext", "CalibrationSelectTool", param);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 相机拍照
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <returns></returns>
|
|
|
|
|
+ private async Task<(bool IsSuccess, double X, double Y, double U, int ImageWidth, int ImageHeight)> CaptureAndProcess()
|
|
|
|
|
+ {
|
|
|
|
|
+ await Task.Delay(200);
|
|
|
|
|
+ //采集图像
|
|
|
|
|
+ if (Camera != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ SelectCalibration.ToolBlock.Inputs["InputImage"].Value = Camera.Grab();
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ App.Current.Dispatcher.Invoke(() =>
|
|
|
|
|
+ {
|
|
|
|
|
+ Graphic = null;
|
|
|
|
|
+ Image = (ICogImage)SelectCalibration.ToolBlock.Inputs["InputImage"].Value;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ SelectCalibration.ToolBlock.Run();
|
|
|
|
|
+ CogToolBlockTerminalCollection outputCollection = SelectCalibration.ToolBlock.Outputs;
|
|
|
|
|
+ App.Current.Dispatcher.Invoke(() =>
|
|
|
|
|
+ {
|
|
|
|
|
+ Graphic = outputCollection["Graphic"].Value as CogGraphicCollection;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ bool Found = (bool)(outputCollection["Found"].Value);
|
|
|
|
|
+ if (Found)
|
|
|
|
|
+ {
|
|
|
|
|
+ var strpoints = outputCollection["Point"].Value.ToString();
|
|
|
|
|
+ string[] items = strpoints.Split(',');
|
|
|
|
|
+ double x = double.Parse(items[0]);
|
|
|
|
|
+ double y = double.Parse(items[1]);
|
|
|
|
|
+ return (true, x, y, 0, Image.Width, Image.Height);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ return (false, 0, 0, 0, Image.Width, Image.Height);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #endregion
|
|
|
|
|
+
|
|
|
|
|
+ #region 继承
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 确认导航请求时调用。此方法允许您在导航之前执行一些操作。
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="navigationContext"></param>
|
|
|
|
|
+ /// <param name="continuationCallback"></param>
|
|
|
|
|
+ public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
|
|
|
|
|
+ {
|
|
|
|
|
+ continuationCallback(true);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 接收导航请求时调用。传入导航参数,包含有关导航目标的信息。
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="navigationContext"></param>
|
|
|
|
|
+ /// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
+ public async void OnNavigatedTo(NavigationContext navigationContext)
|
|
|
|
|
+ {
|
|
|
|
|
+ SelectCalibration = navigationContext.Parameters.GetValue<CalibrationInfo>("SelectCalibration");
|
|
|
|
|
+ if (SelectCalibration != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ Robot = _robotService.GetRobot(SelectCalibration.RobotId);
|
|
|
|
|
+ }
|
|
|
|
|
+ Camera = _cameraService.GetCamera(SelectCalibration.CameraID);
|
|
|
|
|
+ _cameraCalibrationService.CaptureAndProcessCallback = null;
|
|
|
|
|
+ _cameraCalibrationService.CaptureAndProcessCallback = CaptureAndProcess;
|
|
|
|
|
+ if (_systemDatabaseService.GetCurrentUser().userPart == Enums.UserPart.Operator)
|
|
|
|
|
+ {
|
|
|
|
|
+ IsAllowEdit = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ IsAllowEdit = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 是否允许导航到此视图模型。
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="navigationContext"></param>
|
|
|
|
|
+ /// <returns></returns>
|
|
|
|
|
+ public bool IsNavigationTarget(NavigationContext navigationContext)
|
|
|
|
|
+ {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /// <summary>
|
|
|
|
|
+ /// 导航离开此视图模型时调用。您可以在此处执行清理操作或保存状态。
|
|
|
|
|
+ /// </summary>
|
|
|
|
|
+ /// <param name="navigationContext"></param>
|
|
|
|
|
+ public void OnNavigatedFrom(NavigationContext navigationContext)
|
|
|
|
|
+ {
|
|
|
|
|
+ _cameraCalibrationService.CaptureAndProcessCallback = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ #endregion
|
|
|
|
|
+
|
|
|
|
|
+ private bool _IsAllowEdit = false;
|
|
|
|
|
+
|
|
|
|
|
+ public bool IsAllowEdit
|
|
|
|
|
+ {
|
|
|
|
|
+ get { return _IsAllowEdit; }
|
|
|
|
|
+ set { SetProperty(ref _IsAllowEdit, value); }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void LoginChange(Models.User user)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (user.userPart == Enums.UserPart.Operator)
|
|
|
|
|
+ {
|
|
|
|
|
+ IsAllowEdit = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ IsAllowEdit = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|