using MainShell.Common; using MainShell.Common.Display.Models; using MainShell.Log; using MainShell.Motion; using Maxwell.SemiFramework.DefaultConfig.Vision; using MwFramework.Controls.Components; using MwFramework.Controls.ControlCanvas.Model; using MwFramework.Controls.UIControl; using MwFramework.Device; using MwFramework.ManagerService; using Stylet; using StyletIoC; using System; using System.Collections.ObjectModel; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; namespace MainShell.Common.Display.ViewModel { public class CameraAxisViewModel : Screen { private const double DefaultFovX = 14.1 * 10; private const double DefaultFovY = 10.3 * 10; private const string SafeAxisMotionNotInjectedMessage = "SafeAxisMotion is not injected."; private readonly object _moveLock = new object(); private CameraAxisDevices _cameraAxisDevices = new CameraAxisDevices(); private double _xPixelPos; private double _yPixelPos; private double _cameraXIndex; private double _cameraYIndex; private GetConvertValue _convertFunXDelegate; private GetConvertValue _convertFunYDelegate; private ObservableCollection _regions = new ObservableCollection(); private bool _isCameraEnable = true; private Visibility _controlVisibility = Visibility.Visible; private bool _isOpen; [Inject] public SafeAxisMotion SafeAxisMotion { get; set; } public CameraAxisViewModel() { ConvertFunXDelegate = new GetConvertValue(ConvertFunX); ConvertFunYDelegate = new GetConvertValue(ConvertFunY); OnLeftMouseDownCommand = new DelegateCommand(OnLeftMouseDown); } public CameraAxisDevices CameraAxisDevices { get { return _cameraAxisDevices; } set { SetAndNotify(ref _cameraAxisDevices, value); } } public double XPixelPos { get { return _xPixelPos; } set { SetAndNotify(ref _xPixelPos, value); } } public double YPixelPos { get { return _yPixelPos; } set { SetAndNotify(ref _yPixelPos, value); } } public double CameraXIndex { get { return _cameraXIndex; } set { SetAndNotify(ref _cameraXIndex, value); } } public double CameraYIndex { get { return _cameraYIndex; } set { SetAndNotify(ref _cameraYIndex, value); } } public GetConvertValue ConvertFunXDelegate { get { return _convertFunXDelegate; } set { SetAndNotify(ref _convertFunXDelegate, value); } } public GetConvertValue ConvertFunYDelegate { get { return _convertFunYDelegate; } set { SetAndNotify(ref _convertFunYDelegate, value); } } public ObservableCollection Regions { get { return _regions; } set { SetAndNotify(ref _regions, value); } } public bool IsCameraEnable { get { return _isCameraEnable; } set { SetAndNotify(ref _isCameraEnable, value); } } public Visibility ControlVisibility { get { return _controlVisibility; } set { SetAndNotify(ref _controlVisibility, value); } } public ICommand OnLeftMouseDownCommand { get; private set; } public bool IsOpen { get { return _isOpen; } set { SetAndNotify(ref _isOpen, value); } } public void OnLeftMouseDown(object sender) { try { HardwareDevice selectedDevice; if (!TryGetSelectedDevice(out selectedDevice)) { return; } CameraAxisControlA controlA = sender as CameraAxisControlA; if (controlA == null) { return; } Point pixelPos = new Point(controlA.YPixPos, controlA.XPixPos); Task.Run(() => MoveToPixelPoint(selectedDevice, pixelPos, false)); } catch (Exception ex) { LogManager.LogSysError(ex); ShowOperationFailed(ex.Message); } } public void MovePosAction() { try { HardwareDevice selectedDevice; if (!TryGetSelectedDevice(out selectedDevice)) { return; } Point pixelPos = new Point(YPixelPos, XPixelPos); Task.Run(() => MoveToPixelPoint(selectedDevice, pixelPos, true)); } catch (Exception ex) { LogManager.LogSysError(ex); ShowOperationFailed(ex.Message); } } public double ConvertFunX(double interval) { try { HardwareDevice selectedDevice; if (!TryGetSelectedDevice(out selectedDevice)) { return 0; } string name = selectedDevice.Camera.Id; double dx; double dy; VisionProcess.Instance.GetCameraResolution(name, out dx, out dy); double pixelX = interval / Math.Abs(dx); return pixelX; } catch (Exception ex) { LogManager.LogSysError(ex); ShowOperationFailed(ex.Message); return 0; } } public double ConvertFunY(double interval) { try { HardwareDevice selectedDevice; if (!TryGetSelectedDevice(out selectedDevice)) { return 0; } string name = selectedDevice.Camera.Id; double dx; double dy; VisionProcess.Instance.GetCameraResolution(name, out dx, out dy); double pixelY = interval / Math.Abs(dy); return pixelY; } catch (Exception ex) { LogManager.LogSysError(ex); ShowOperationFailed(ex.Message); return 0; } } private bool TryGetSelectedDevice(out HardwareDevice selectedDevice) { selectedDevice = CameraAxisDevices != null ? CameraAxisDevices.SelectedHardwareDevice : null; if (!IsOpen || selectedDevice == null) { return false; } if (selectedDevice.Camera == null || selectedDevice.Camera.Camera == null) { ShowDeviceNotInitialized(); return false; } if (!selectedDevice.Camera.Camera.IsGrabbing) { LocalizedMessageBox.Show(MessageKey.VisionCameraNotGrabbing, MessageKey.TitleWarning, MessageBoxButton.OK, MessageBoxImage.Warning); return false; } if (selectedDevice.AxisX == null || selectedDevice.AxisY == null) { ShowDeviceNotInitialized(); return false; } return true; } private void MoveToPixelPoint(HardwareDevice selectedDevice, Point pixelPos, bool requireConfirmation) { lock (_moveLock) { try { IAxis axisX = selectedDevice.AxisX; IAxis axisY = selectedDevice.AxisY; Point rulerPos = new Point(axisX.State.ActualPos, axisY.State.ActualPos); Point newRulerPoint = Algorithm.Instance.MoveToPixelPoint(selectedDevice.Camera.Id, rulerPos, pixelPos); if (requireConfirmation) { double dx = newRulerPoint.X - rulerPos.X; double dy = newRulerPoint.Y - rulerPos.Y; if (!ValidateMoveRange(dx, dy)) { return; } if (!ConfirmMove(newRulerPoint)) { return; } } if (SafeAxisMotion == null) { InvalidOperationException exception = new InvalidOperationException(SafeAxisMotionNotInjectedMessage); LogManager.LogSysError(exception); ShowOperationFailed(SafeAxisMotionNotInjectedMessage); return; } SafeAxisMotion.SafeMove( MotionMoveRequest.ForAxis(axisX, newRulerPoint.X), MotionMoveRequest.ForAxis(axisY, newRulerPoint.Y)); } catch (Exception ex) { LogManager.LogSysError(ex); ShowOperationFailed(ex.Message); } } } private static bool ValidateMoveRange(double dx, double dy) { if (Math.Abs(dx) > DefaultFovX || Math.Abs(dy) > DefaultFovY) { LocalizedMessageBox.Show(MessageKey.ParamOutOfRange, MessageKey.TitleWarning, MessageBoxButton.OK, MessageBoxImage.Warning); return false; } return true; } private static bool ConfirmMove(Point newRulerPoint) { string message = string.Format("新点的坐标({0},{1}),是否移动?", newRulerPoint.X, newRulerPoint.Y); return MwMessageBox.Show(message, LanguageResourceHelper.GetString(MessageKey.TitleConfirm), MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK; } private static void ShowDeviceNotInitialized() { LocalizedMessageBox.Show(MessageKey.DeviceNotInitialized, MessageKey.TitleWarning, MessageBoxButton.OK, MessageBoxImage.Warning); } private static void ShowOperationFailed(string message) { if (string.IsNullOrWhiteSpace(message)) { LocalizedMessageBox.Show(MessageKey.CommonOperationFailed, MessageKey.TitleError, MessageBoxButton.OK, MessageBoxImage.Error); return; } MwMessageBox.Show(message, LanguageResourceHelper.GetString(MessageKey.TitleError), MessageBoxButton.OK, MessageBoxImage.Error); } } }