using Aurora; using Aurora.Api; using Aurora.View; using AuroraLaser; using AuroraLaserScanner; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Input; using System.Windows.Threading; namespace WeldingCommon.Views { public class UCScannerLaserControlViewModel : NotifyPropertyChangedBase { private readonly Logger Log = new Logger("UCScannerLaserControlViewModel"); public ICommand CMD_VisibleChanged { get; } public ICommand CMD_LaserShotOn { get; } public ICommand CMD_LaserShotOff { get; } public ICommand CMD_ActivateOnTheFly { get; } public ICommand CMD_DeactivateOnTheFly { get; } public ICommand CMD_ResetEncoderValue { get; } public ICommand CMD_SimulateEncoder { get; } public ICommand CMD_SimulateEncoderXY { get; } private readonly IAuroraEnvironment _Aurora; private readonly Scanner _Scanner; private readonly ILaserDevice _Laser; private readonly ScannerConfig _ScannerConfig; private double _LaserPower1; public double LaserPower1 { get => _LaserPower1; set => SetProperty(ref _LaserPower1, value); } private double _LaserPower2; public double LaserPower2 { get => _LaserPower2; set => SetProperty(ref _LaserPower2, value); } private uint _LaserPeriod; public uint LaserPeriod { get => _LaserPeriod; set => SetProperty(ref _LaserPeriod, value); } private uint _LaserPulseWidth; public uint LaserPulseWidth { get => _LaserPulseWidth; set => SetProperty(ref _LaserPulseWidth, value); } private bool _IsUseLaserAutoOffChecked; public bool IsUseLaserAutoOffChecked { get => _IsUseLaserAutoOffChecked; set => SetProperty(ref _IsUseLaserAutoOffChecked, value); } private double _LaserOnTime; public double LaserOnTime { get => _LaserOnTime; set => SetProperty(ref _LaserOnTime, value); } // List1 or List2 를 Scanner 의 상태를 보고 check private string _BusyStatus; public string BusyStatus { get => _BusyStatus; set => SetProperty(ref _BusyStatus, value); } private int _ListInterationCount; public int ListInterationCount { get => _ListInterationCount; set => SetProperty(ref _ListInterationCount, value); } private double _RotateCenterX; public double RotateCenterX { get => _RotateCenterX; set => SetProperty(ref _RotateCenterX, value); } private double _RotateCenterY; public double RotateCenterY { get => _RotateCenterY; set => SetProperty(ref _RotateCenterY, value); } private double _EncoderResolution; public double EncoderResolution { get => _EncoderResolution; set => SetProperty(ref _EncoderResolution, value); } private double _EncoderValueAxisX; public double EncoderValueAxisX { get => _EncoderValueAxisX; set => SetProperty(ref _EncoderValueAxisX, value); } private double _EncoderValueAxisY; public double EncoderValueAxisY { get => _EncoderValueAxisY; set => SetProperty(ref _EncoderValueAxisY, value); } private double _EncoderValueRotate; public double EncoderValueRotate { get => _EncoderValueRotate; set => SetProperty(ref _EncoderValueRotate, value); } private double _EncoderValueVelocity; public double EncoderValueVelocity { get => _EncoderValueVelocity; set => SetProperty(ref _EncoderValueVelocity, value); } private bool _IsFieldOutX; public bool IsFieldOutX { get => _IsFieldOutX; set => SetProperty(ref _IsFieldOutX, value); } private bool _IsFieldOutY; public bool IsFieldOutY { get => _IsFieldOutY; set => SetProperty(ref _IsFieldOutY, value); } private bool _IsUseMarkingOnTheFly; public bool IsUseMarkingOnTheFly { get => _IsUseMarkingOnTheFly; set => SetProperty(ref _IsUseMarkingOnTheFly, value); } private int _BeforeBusyList = 0; private int _ListIterationCount = 0; private DateTime _LastEncRecordTime = DateTime.Now; private double _LastEncoderRecorded = 0; private bool _ToggleSimulateEncoder = false; // 왜 있는지는 모르겠음. private readonly DispatcherTimer _MonitorTimer; public UCScannerLaserControlViewModel(IAuroraEnvironment aurora, string scannerId, bool isUseMarkingOntheFly = false) { _Aurora = aurora; _Scanner = _Aurora.DeviceManager[scannerId] as Scanner; _Laser = _Aurora.DeviceManager[CommonDeviceIds.Laser] as ILaserDevice; _ScannerConfig = _Aurora.DeviceManager.GetDeviceConfig(scannerId) as ScannerConfig; IsUseMarkingOnTheFly = isUseMarkingOntheFly; InitVariable(); CMD_VisibleChanged = new DelegateCommand(VisibleChanged); CMD_LaserShotOn = new DelegateCommand(PerformCmdLaserShotOn); CMD_LaserShotOff = new DelegateCommand(PerformCmdLaserShotOff); CMD_ActivateOnTheFly = new DelegateCommand(PerformCmdActivateOnTheFly); CMD_DeactivateOnTheFly = new DelegateCommand(PerformCmdDeactivateOnTheFly); CMD_ResetEncoderValue = new DelegateCommand(PerformCmdResetEncoderValue); CMD_SimulateEncoder = new DelegateCommand(PerformCmdSimulateEncoder); CMD_SimulateEncoderXY = new DelegateCommand(PerformCmdSimulateEncoderXY); _MonitorTimer = new DispatcherTimer(); _MonitorTimer.Tick += OnMonitoring; _MonitorTimer.Interval = TimeSpan.FromMilliseconds(100); } private void InitVariable() { LaserPower1 = 10; LaserPower2 = 0; LaserPeriod = 1; LaserPulseWidth = 1000; _LastEncRecordTime = DateTime.Now; IsUseLaserAutoOffChecked = true; } private void VisibleChanged(object obj) { bool visible = (bool)obj; if (visible) { //Init_XYLimitPos(); _MonitorTimer.Start(); } else { _MonitorTimer.Stop(); } } private void OnMonitoring(object sender, EventArgs e) { if (_Scanner.IsActivated == false) { Log.D(string.Format("[OnMonitoring] Check Scanner device Connect. ScannerLaserControl view OnMonitoring Stop")); MessageUtil.ShowWarningToast(string.Format("Check Scanner device Connect.")); _MonitorTimer.Stop(); } double encoderX = 0; double encoderY = 0; if (_ScannerConfig.OnTheFlyCoordinate == eOntheFlyCoordinate.XY) { _Scanner.GetEncoder(out encoderX, out encoderY, false); EncoderValueAxisX = encoderX; EncoderValueAxisY = encoderY; } else { _Scanner.GetEncoder(out encoderX, out encoderY, true); EncoderValueRotate = encoderX; // encoderX와 encoderY는 같은 값을 받음. } TimeSpan encRecordTimeSpan = DateTime.Now.Subtract(_LastEncRecordTime); _LastEncRecordTime = DateTime.Now; //// CBW Test용 임시 수정 ////m_scannerUnit.GetEncoder(out encoderX, out encoderY, true); //EncoderValueAxisX = encoderX; //EncoderValueAxisY = encoderY; ////m_scannerUnit.GetEncoder(out encoderX, out encoderY, true); ////lbRotateEncoderValue.Text = (encoderX).ToString("f3"); //EncoderValueRotate = 0; EncoderValueVelocity = (encoderX - _LastEncoderRecorded) / (encRecordTimeSpan.TotalSeconds); _LastEncoderRecorded = encoderX; //// Field 초과 판단 uint markingInfo = 0; markingInfo = _Scanner.GetMarkingInfo(); // x 범위 초과 if ((markingInfo & 0x0001) == 0x0001 || (markingInfo & 0x0002) == 0x0002) { IsFieldOutX = true; } else { IsFieldOutX = false; } // y 범위 초과 if ((markingInfo & 0x0004) == 0x0004 || (markingInfo & 0x0008) == 0x0008) { IsFieldOutY = true; } else { IsFieldOutY = false; } // 상태 파악 및 반복성 확인. uint readStatus = _Scanner.ReadStatus(); string busyStatus; uint IsList1Busy = readStatus & 16; uint IsList2Busy = readStatus & 32; if (IsList1Busy == 16) { busyStatus = "List1"; if (_BeforeBusyList != 1) { _ListIterationCount++; } _BeforeBusyList = 1; } else if (IsList2Busy == 32) { busyStatus = "List2"; if (_BeforeBusyList != 2) { _ListIterationCount++; } _BeforeBusyList = 2; } else { busyStatus = "N/A"; } BusyStatus = busyStatus; ListInterationCount = _ListIterationCount; } private void PerformCmdLaserShotOn(object obj) { if (_Scanner.GetBusyStatus()) { MessageUtil.ShowWarningToast(string.Format("Laser, Scanner is busy.")); return; } if (!_Laser.GetLaserReady()) { MessageUtil.ShowWarningToast(string.Format("Laser, Check Laser Ready status.")); return; } _Scanner.SetStartList(eListNo.LIST1); _Scanner.SetLaserTiming(LaserPeriod, LaserPulseWidth * 1000, LaserPulseWidth * 1000); _Scanner.SetStandby(LaserPeriod, LaserPulseWidth * 1000); if (IsUseLaserAutoOffChecked) { _Scanner.LaserOnList(LaserOnTime); } _Scanner.WriteDA((uint)eAnalogPortOut.DA1, (float)LaserPower1, eFunctionType.LIST); _Scanner.WriteDA((uint)eAnalogPortOut.DA2, (float)LaserPower2, eFunctionType.LIST); _Scanner.SetEndList(); _Scanner.ExecuteList(eListNo.LIST1); if (IsUseLaserAutoOffChecked == false) { Thread.Sleep(50); _Scanner.WriteDA((uint)eAnalogPortOut.DA1, (float)LaserPower1, eFunctionType.COMMAND); _Scanner.WriteDA((uint)eAnalogPortOut.DA1, (float)LaserPower2, eFunctionType.COMMAND); _Scanner.SetLaserTiming(LaserPeriod, LaserPulseWidth * 1000, LaserPulseWidth * 1000); _Scanner.SetStandby(LaserPeriod, LaserPulseWidth * 1000); _Scanner.LaserSignalOn(); } } private void PerformCmdLaserShotOff(object obj) { if (IsUseLaserAutoOffChecked) { _Scanner.StopExecution(); } else { _Scanner.LaserSignalOff(); } _Scanner.SetStandby(10, 0); } private void PerformCmdResetEncoderValue(object obj) { try { _Scanner.InitFly2D(); // CBW OTW 테스트를 위해 아래는 일단 주석처리 //m_scannerUnit.SetFlyX(m_scannerUnit.ScannerUnitParamObj.MarkingOnTheFlyEncoderResolutionX); // list 반복 숫자 초기화 _ListIterationCount = 0; } catch (Exception ex) { MessageUtil.ShowErrorToast(string.Format($"{ex.Message}")); } } private void PerformCmdActivateOnTheFly(object obj) { _Scanner.SetRotateCenter(RotateCenterX, RotateCenterY); // list 1 _Scanner.SetStartList(eListNo.LIST1); _Scanner.SetFlyRotate(EncoderResolution); _Scanner.SetLaserTiming(10, 100, 100); // 아무거나 _Scanner.SetStandby(10, 0); // 아무거나 _Scanner.LaserOnList(LaserOnTime); // 1000이 1초 _Scanner.SetEndList(); // End - list1 _Scanner.ExecuteList(eListNo.LIST1); } private void PerformCmdDeactivateOnTheFly(object obj) { _Scanner.SetStartList(eListNo.LIST1); _Scanner.Fly_Return(0, 0); _Scanner.SetEndList(); _Scanner.ExecuteList(eListNo.LIST1); } private void PerformCmdSimulateEncoder(object obj) { if (_ToggleSimulateEncoder) { _Scanner.SimulateEncoder(0); _ToggleSimulateEncoder = false; } else { _ToggleSimulateEncoder = true; _Scanner.SimulateEncoder(1); } } private void PerformCmdSimulateEncoderXY(object obj) { if (_ToggleSimulateEncoder) { _Scanner.SimulateEncoder(0); _ToggleSimulateEncoder = false; } else { _ToggleSimulateEncoder = true; _Scanner.SimulateEncoder(3); } } // 일단 이건 1 source 에서 가져옴. view 에서 주석처리 된 부분 //private void ApplyAnalogValue(object obj) //{ // try { // //DA1, DA2 Combobox 이벤트로 현재값을 AnalogVaule에 보여주고싶으나 해야될게많다.. // //일단 유저가 셋팅만 해서 쓰는 걸로하자.. // if (AnalogPortSelectedIndex == 0) { // DA1PercentLaser = (float)AnalogValue; // } else if (AnalogPortSelectedIndex == 1) { // DA2PercentLaser = (float)AnalogValue; // } else { // MessageDialog.Show(Application.Current.MainWindow, "LaserManual", "Check AnalogPortIndex", MessageDialog.Type.Affirmative); // } // } catch (Exception ex) { // Log.E(string.Format($"{ex.Message}")); // } //} } }