using Aurora; using Aurora.Api; using Aurora.View; using AuroraLaser; using AuroraLaserScanner; using CoreUnit.Control.UserControl.Canvas; using CoreUnit.Scanner.UserControl.ScannerCanvas; 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; using WeldingCommon.Models; using WeldingCommon.Sequences; using WeldingCommon.Settings; using WeldingCommon.Utils; namespace WeldingCommon.Views { public class UCScannerLaserControlViewModel : NotifyPropertyChangedBase { private readonly Logger Log = new Logger("UCScannerLaserControlViewModel"); public ICommand CMD_VisibleChanged { get; } public ICommand CMD_LaserShotOnPercent { 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; } public ICommand CMD_LaserShotOnWatt { get; } private readonly IAuroraEnvironment _Aurora; private readonly LaserConfig _LaserConfig; private readonly Scanner _Scanner; private readonly Laser _Laser; private readonly ScannerConfig _ScannerConfig; private double _LaserPower1Percent; public double LaserPower1Percent { get => _LaserPower1Percent; set => SetProperty(ref _LaserPower1Percent, value); } private double _LaserPower2Percent; public double LaserPower2Percent { get => _LaserPower2Percent; set => SetProperty(ref _LaserPower2Percent, value); } private double _LaserPower1Watt; public double LaserPower1Watt { get => _LaserPower1Watt; set => SetProperty(ref _LaserPower1Watt, value); } private double _LaserPower2Watt; public double LaserPower2Watt { get => _LaserPower2Watt; set => SetProperty(ref _LaserPower2Watt, 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; private ISequence _SeqTeachingRun; public UCScannerLaserControlViewModel(IAuroraEnvironment aurora, string scannerId, bool isUseMarkingOntheFly = false) { _Aurora = aurora; _Scanner = _Aurora.DeviceManager[scannerId] as Scanner; _Laser = _Aurora.DeviceManager[CommonDeviceIds.Laser] as Laser; _LaserConfig = _Aurora.DeviceManager.GetDeviceConfig(_Laser.DeviceId) as AuroraLaser.LaserConfig; _ScannerConfig = _Aurora.DeviceManager.GetDeviceConfig(scannerId) as ScannerConfig; _SeqTeachingRun = _Aurora.SequenceEntry[CommonSequenceIds.SeqComponentTeachingRun]; IsUseMarkingOnTheFly = isUseMarkingOntheFly; InitVariable(); CMD_VisibleChanged = new DelegateCommand(VisibleChanged); CMD_LaserShotOnPercent = new DelegateCommand(PerformCmdLaserShotOnPercent); CMD_LaserShotOnWatt = new DelegateCommand(PerformCmdLaserShotOnWatt); 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() { LaserPower1Percent = 10; LaserPower2Percent = 0; LaserPeriod = 1; LaserPulseWidth = 1000000; LaserPower1Watt = 300; LaserPower2Watt = 0; _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, encoderY; if (_ScannerConfig.OnTheFlyCoordinate == eOntheFlyCoordinate.XY) { _Scanner.GetEncoder(out encoderX, out encoderY, false); } else { _Scanner.GetEncoder(out encoderX, out encoderY, true); } 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 PerformCmdLaserShotOnPercent(object obj) { if (IsUseLaserAutoOffChecked) { 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; } if (_SeqTeachingRun.RunState == SequenceRunState.Running) { MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "Laser On"), Log); return; } var currentModelInfo = EquipmentSpecificModelUtil.GetCurrentRecipeEquipmentSpecificModel(); if (currentModelInfo.equipmentSpecificModel == null) { MessageUtil.ShowWarningToast(string.Format("선택된 model 이 없습니다.", "Laser On")); return; } var intervalTimeBlowOn = 0; var intervalTimeBlowOff = 0; if (currentModelInfo.equipmentSpecificModel.UseBlow) { intervalTimeBlowOn = currentModelInfo.equipmentSpecificModel.IntervalTimeBlowOn; intervalTimeBlowOff = currentModelInfo.equipmentSpecificModel.IntervalTimeBlowOff; } // Object를 만들어 var param = new SeqTeachingRun_InitParam() { IsUseExternalObjects = true, ExternalObjects = CreateDotForLaserOn(), //UseStream = _EquipmentInfo.UseStream, UseStream = currentModelInfo.equipmentSpecificModel.UseStream, UseBlow = currentModelInfo.equipmentSpecificModel.UseBlow, IntervalTimeBlowOn = intervalTimeBlowOn, IntervalTimeBlowOff = intervalTimeBlowOff, NeedSetLaserTiming = true, }; _SeqTeachingRun.Start(param, OnCompleteMarkGrid); } else { LaserPowerCalParam powerCalParam = Status.AuroraEnv.SettingEntry[CommonSettingIds.LaserPowerCalParam] as LaserPowerCalParam; float powerVolt1 = 0, powerVolt2 = 0; powerCalParam.Initialize(powerCalParam.PowerCalibrationCenterBeamCSVFile, powerCalParam.PowerCalibrationRingBeamCSVFile); if (_LaserConfig.TruFiberType == eTruFiberType.TruFiberS) { powerVolt1 = (float)powerCalParam.CalibratePercentToMeasuredVoltage(LaserPower1Percent) * 10; } else if(_LaserConfig.TruFiberType == eTruFiberType.TruFiberP){ powerVolt1 = (float)powerCalParam.CalibratePercentToMeasuredVoltage(LaserPower1Percent, (uint)LaserPowerCalParam.beamMode.Center) * 10; powerVolt2 = (float)powerCalParam.CalibratePercentToMeasuredVoltage(LaserPower2Percent, (uint)LaserPowerCalParam.beamMode.Ring) * 10; } else if (_Laser.Config.TruFiberType == eTruFiberType.CalPercentToMeasuredVoltage) { powerVolt1 = (float)powerCalParam.CalibratePercentToMeasuredVoltage(LaserPower1Percent, (uint)LaserPowerCalParam.beamMode.Center) * 10; powerVolt2 = (float)powerCalParam.CalibratePercentToMeasuredVoltage(LaserPower2Percent, (uint)LaserPowerCalParam.beamMode.Ring) * 10; } else { powerVolt1 = (float)powerCalParam.CalibratePercentToMeasuredVoltage(LaserPower1Percent, (uint)LaserPowerCalParam.beamMode.Center) * 10; powerVolt2 = (float)powerCalParam.CalibratePercentToMeasuredVoltage(LaserPower2Percent, (uint)LaserPowerCalParam.beamMode.Ring) * 10; } Thread.Sleep(50); _Scanner.WriteDA((uint)eAnalogPortOut.DA1, powerVolt1, eFunctionType.COMMAND); _Scanner.WriteDA((uint)eAnalogPortOut.DA2, powerVolt2, eFunctionType.COMMAND); _Scanner.SetLaserPulseCtrl(LaserPeriod * 1000, LaserPulseWidth); //_Scanner.SetLaserTiming(LaserPeriod * 1000, LaserPulseWidth, LaserPulseWidth); //_Scanner.SetStandby(LaserPeriod * 1000, LaserPulseWidth); _Scanner.LaserSignalOn(); } } private void PerformCmdLaserShotOnWatt(object obj) { if (IsUseLaserAutoOffChecked) { 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; } if (_SeqTeachingRun.RunState == SequenceRunState.Running) { MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "Laser On"), Log); return; } var currentModelInfo = EquipmentSpecificModelUtil.GetCurrentRecipeEquipmentSpecificModel(); if (currentModelInfo.equipmentSpecificModel == null) { MessageUtil.ShowWarningToast(string.Format("선택된 model 이 없습니다.", "Laser On")); return; } var intervalTimeBlowOn = 0; var intervalTimeBlowOff = 0; if (currentModelInfo.equipmentSpecificModel.UseBlow) { intervalTimeBlowOn = currentModelInfo.equipmentSpecificModel.IntervalTimeBlowOn; intervalTimeBlowOff = currentModelInfo.equipmentSpecificModel.IntervalTimeBlowOff; } // Object를 만들어 var param = new SeqTeachingRun_InitParam() { IsUseExternalObjects = true, ExternalObjects = CreateDotForLaserOn(), //UseStream = _EquipmentInfo.UseStream, UseStream = currentModelInfo.equipmentSpecificModel.UseStream, UseBlow = currentModelInfo.equipmentSpecificModel.UseBlow, IntervalTimeBlowOn = intervalTimeBlowOn, IntervalTimeBlowOff = intervalTimeBlowOff, NeedSetLaserTiming = true, }; _SeqTeachingRun.Start(param, OnCompleteMarkGrid); } else { LaserPowerCalParam powerCalParam = Status.AuroraEnv.SettingEntry[CommonSettingIds.LaserPowerCalParam] as LaserPowerCalParam; float powerVolt1 = 0, powerVolt2 = 0; powerCalParam.Initialize(powerCalParam.PowerCalibrationCenterBeamCSVFile, powerCalParam.PowerCalibrationRingBeamCSVFile); if (_LaserConfig.TruFiberType == eTruFiberType.TruFiberS) { powerVolt1 = (float)powerCalParam.CalibrateWattToMeasuredVoltage(LaserPower1Watt) * 10; } else if (_LaserConfig.TruFiberType == eTruFiberType.TruFiberP) { powerVolt1 = (float)powerCalParam.CalibrateWattToMeasuredVoltage(LaserPower1Watt, (uint)LaserPowerCalParam.beamMode.Center) * 10; powerVolt2 = (float)powerCalParam.CalibrateWattToMeasuredVoltage(LaserPower2Watt, (uint)LaserPowerCalParam.beamMode.Ring) * 10; } else if (_Laser.Config.TruFiberType == eTruFiberType.CalPercentToMeasuredVoltage) { powerVolt1 = (float)powerCalParam.CalibrateWattToMeasuredVoltage(LaserPower1Watt, (uint)LaserPowerCalParam.beamMode.Center) * 10; powerVolt2 = (float)powerCalParam.CalibrateWattToMeasuredVoltage(LaserPower2Watt, (uint)LaserPowerCalParam.beamMode.Ring) * 10; } else { powerVolt1 = (float)powerCalParam.CalibratePercentToMeasuredVoltage(LaserPower1Percent, (uint)LaserPowerCalParam.beamMode.Center) * 10; powerVolt2 = (float)powerCalParam.CalibratePercentToMeasuredVoltage(LaserPower2Percent, (uint)LaserPowerCalParam.beamMode.Ring) * 10; } Thread.Sleep(50); _Scanner.WriteDA((uint)eAnalogPortOut.DA1, powerVolt1, eFunctionType.COMMAND); _Scanner.WriteDA((uint)eAnalogPortOut.DA2, powerVolt2, eFunctionType.COMMAND); _Scanner.SetLaserPulseCtrl(LaserPeriod * 1000, LaserPulseWidth); //_Scanner.SetLaserTiming(LaserPeriod * 1000, LaserPulseWidth, LaserPulseWidth); //_Scanner.SetStandby(LaserPeriod * 1000, LaserPulseWidth); _Scanner.LaserSignalOn(); } } private void OnCompleteMarkGrid(SequenceActionResult res) { if (res != null) { if (res.Param is SeqTeachingRun_OutParam result && result.Success == true) { MessageUtil.ShowSuccessToast(string.Format("Success SeqMarkGrid")); return; } } MessageUtil.ShowWarningToast(string.Format("Fail SeqMarkGrid")); } 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); } } private List CreateDotForLaserOn() { LaserPowerCalParam powerCalParam = Status.AuroraEnv.SettingEntry[CommonSettingIds.LaserPowerCalParam] as LaserPowerCalParam; ScannerParam param = new ScannerParam(); param.LaserPower1 = (uint)(LaserPower1Percent / 100 * LaserPowerCalParam.MaxCenterPower);// = LaserPower1; // 변경 필요 param.LaserPower2 = (uint)(LaserPower2Percent / 100 * LaserPowerCalParam.MaxRingPower);// = LaserPower1; // 변경 필요 param.MarkSpeed = 200; param.JumpSpeed = 1000; param.SpotShotTime = LaserOnTime; // 변경 필요 param.LaserFrequency = 1000; param.LaserPulseDuration = 1000; param.MarkDelay = 200; param.JumpDelay = 200; param.PolygonDelay = 200; ScannerCanvasUserCtrl.ScannerParams[127] = param; Dot dot = new Dot(); _Scanner.GetXYPos(out double xPos, out double yPos); dot.P1 = new UnitPoint(xPos, yPos); dot.Enabled = true; dot.Selected = true; dot.ScannerParamNo = 127; List drawObjects = new List(); drawObjects.Add(dot); return drawObjects; } // 일단 이건 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}")); // } //} } }