From d7cae996efe6be216c1e8dc68a94a7d31050b9d6 Mon Sep 17 00:00:00 2001 From: NohDoyeon241104 Date: Mon, 13 Apr 2026 11:42:54 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20WeldingCommon=EC=9D=98=20=EA=B0=81?= =?UTF-8?q?=20=ED=8F=B4=EB=8D=94=EC=97=90=20Gun=20=ED=8F=B4=EB=8D=94=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=ED=9B=84=20Gun=EC=9D=98=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85=EA=B3=BC=20=EB=A0=88=EC=8B=9C=ED=94=BC=20=EA=B7=B8?= =?UTF-8?q?=EB=A6=AC=EA=B3=A0=20=EC=8B=9C=ED=80=B8=EC=8A=A4=20=EB=93=B1?= =?UTF-8?q?=EC=9D=84=20=EB=B3=B5=EC=82=AC=20=EB=B0=8F=20=EC=83=81=EC=88=98?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=ED=95=A8.=20Alarm=20Code=EB=8A=94=20#?= =?UTF-8?q?=EC=9E=A0=EC=8B=9C=20=EC=A3=BC=EC=84=9D=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=ED=92=80=20=EC=98=88=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Machines/ILSOS_PrismaticGun/EquipmentSetup.cs | 8 +- .../Views/Recipe/UCMainRecipeViewModel.cs | 3 + .../ILSOS_PrismaticScanner/EquipmentSetup.cs | 1 + .../WeldingCommon/CommonEquipmentSetup.cs | 29 +- .../WeldingCommon/Devices/ACS/ScannerACS.cs | 20 + .../WeldingCommon/EquipDefCommon.cs | 78 ++- .../WeldingCommon/Process/Gun/CellState.cs | 60 +++ .../WeldingCommon/Process/Gun/PalletInfo.cs | 101 ++++ .../Process/Gun/ProcessManager.cs | 302 ++++++++++++ .../Gun/SequenceManagerForMainWelder.cs | 122 +++++ .../Services/History/CellHistoryService.cs | 31 ++ .../Gun/Services/History/IHistoryReader.cs | 10 + .../Gun/Services/History/IHistoryWriter.cs | 14 + .../Process/Gun/WeldingDataForPrismaticGun.cs | 85 ++++ .../WeldingCommon/Recipes/Gun/MainRecipe.cs | 240 +++++++++ .../Calibration/SeqScannerCalibration.cs | 2 +- .../Gun/Monitoring/SeqAlarmMonitor.cs | 176 +++++++ .../Sequences/Gun/SeqMotorInit.cs | 172 +++++++ .../WeldingCommon/Sequences/Gun/SeqOneShot.cs | 172 +++++++ .../Sequences/Gun/SeqSplitLine.cs | 360 ++++++++++++++ .../StageA/SeqTeachingPosMoveStageA.cs | 325 +++++++++++++ .../StageA/SeqWeldingCellStageA.cs | 459 ++++++++++++++++++ .../Settings/Gun/LineShotInLinesSetting.cs | 22 + .../Settings/Gun/ManualLaserSetting.cs | 103 ++++ .../Settings/Gun/TeachingPositionSetting.cs | 77 +++ .../WeldingCommon/Settings/SystemParameter.cs | 18 +- .../WeldingCommon/Tools/Gun/CommonChecker.cs | 30 ++ .../WeldingCommon/Tools/Gun/CsvLogger.cs | 88 ++++ .../WeldingCommon/Tools/Gun/DualLogger.cs | 67 +++ .../WeldingCommon/Tools/Gun/UnitConversion.cs | 24 + .../UCScannerCalibrationViewModel.cs | 4 +- .../Views/Recipes/Gun/UCMainRecipe.xaml | 360 ++++++++++++++ .../Views/Recipes/Gun/UCMainRecipe.xaml.cs | 44 ++ .../Recipes/Gun/UCMainRecipeViewModel.cs | 445 +++++++++++++++++ .../WeldingCommon/WeldingCommon.csproj | 30 ++ 35 files changed, 4062 insertions(+), 20 deletions(-) create mode 100644 WeldingComponents/WeldingCommon/Process/Gun/CellState.cs create mode 100644 WeldingComponents/WeldingCommon/Process/Gun/PalletInfo.cs create mode 100644 WeldingComponents/WeldingCommon/Process/Gun/ProcessManager.cs create mode 100644 WeldingComponents/WeldingCommon/Process/Gun/SequenceManagerForMainWelder.cs create mode 100644 WeldingComponents/WeldingCommon/Process/Gun/Services/History/CellHistoryService.cs create mode 100644 WeldingComponents/WeldingCommon/Process/Gun/Services/History/IHistoryReader.cs create mode 100644 WeldingComponents/WeldingCommon/Process/Gun/Services/History/IHistoryWriter.cs create mode 100644 WeldingComponents/WeldingCommon/Process/Gun/WeldingDataForPrismaticGun.cs create mode 100644 WeldingComponents/WeldingCommon/Recipes/Gun/MainRecipe.cs create mode 100644 WeldingComponents/WeldingCommon/Sequences/Gun/Monitoring/SeqAlarmMonitor.cs create mode 100644 WeldingComponents/WeldingCommon/Sequences/Gun/SeqMotorInit.cs create mode 100644 WeldingComponents/WeldingCommon/Sequences/Gun/SeqOneShot.cs create mode 100644 WeldingComponents/WeldingCommon/Sequences/Gun/SeqSplitLine.cs create mode 100644 WeldingComponents/WeldingCommon/Sequences/Gun/SubSequence/StageA/SeqTeachingPosMoveStageA.cs create mode 100644 WeldingComponents/WeldingCommon/Sequences/Gun/SubSequence/StageA/SeqWeldingCellStageA.cs create mode 100644 WeldingComponents/WeldingCommon/Settings/Gun/LineShotInLinesSetting.cs create mode 100644 WeldingComponents/WeldingCommon/Settings/Gun/ManualLaserSetting.cs create mode 100644 WeldingComponents/WeldingCommon/Settings/Gun/TeachingPositionSetting.cs create mode 100644 WeldingComponents/WeldingCommon/Tools/Gun/CommonChecker.cs create mode 100644 WeldingComponents/WeldingCommon/Tools/Gun/CsvLogger.cs create mode 100644 WeldingComponents/WeldingCommon/Tools/Gun/DualLogger.cs create mode 100644 WeldingComponents/WeldingCommon/Tools/Gun/UnitConversion.cs create mode 100644 WeldingComponents/WeldingCommon/Views/Recipes/Gun/UCMainRecipe.xaml create mode 100644 WeldingComponents/WeldingCommon/Views/Recipes/Gun/UCMainRecipe.xaml.cs create mode 100644 WeldingComponents/WeldingCommon/Views/Recipes/Gun/UCMainRecipeViewModel.cs diff --git a/Machines/ILSOS_PrismaticGun/EquipmentSetup.cs b/Machines/ILSOS_PrismaticGun/EquipmentSetup.cs index da2e9d8..f5ee850 100644 --- a/Machines/ILSOS_PrismaticGun/EquipmentSetup.cs +++ b/Machines/ILSOS_PrismaticGun/EquipmentSetup.cs @@ -340,8 +340,8 @@ namespace ILSOS_PrismaticGun public override void RegisterRecipes(RecipeRegister register) { - register(RecipeIds.StageAMainRecipe, new MainRecipe(), - (recipe, item) => new UCMainRecipe() { + register(RecipeIds.StageAMainRecipe, new ILSOS_PrismaticGun.Recipes.MainRecipe(), + (recipe, item) => new ILSOS_PrismaticGun.Views.Recipe.UCMainRecipe() { DataContext = new UCMainRecipeViewModel(AuroraEnv, recipe, item, RecipeIds.StageAMainRecipe) }); @@ -366,9 +366,9 @@ namespace ILSOS_PrismaticGun var Setting = AuroraEnv.SettingEntry[CommonSettingIds.LaserPowerCalParam] as LaserPowerCalParam; Setting.Initialize(Setting.PowerCalibrationCenterBeamCSVFile, Setting.PowerCalibrationRingBeamCSVFile); - register(SettingIds.TeachingPos, new TeachingPositionSetting()); + register(SettingIds.TeachingPos, new ILSOS_PrismaticGun.Settings.TeachingPositionSetting()); - register(SettingIds.ManualLaser, new ManualLaserSetting()); + register(SettingIds.ManualLaser, new ILSOS_PrismaticGun.Settings.ManualLaserSetting()); VisionFactory.RegisterSetting(AuroraEnv, register); } diff --git a/Machines/ILSOS_PrismaticGun/Views/Recipe/UCMainRecipeViewModel.cs b/Machines/ILSOS_PrismaticGun/Views/Recipe/UCMainRecipeViewModel.cs index 8fc0d59..25ade05 100644 --- a/Machines/ILSOS_PrismaticGun/Views/Recipe/UCMainRecipeViewModel.cs +++ b/Machines/ILSOS_PrismaticGun/Views/Recipe/UCMainRecipeViewModel.cs @@ -42,6 +42,9 @@ using WeldingCommon.Utils.Diff; using static WeldingCommon.Devices.PLCController; using DelegateCommand = Aurora.View.DelegateCommand; +using eTeachingPosition = ILSOS_PrismaticGun.Settings.eTeachingPosition; +using TeachingPositionSetting = ILSOS_PrismaticGun.Settings.TeachingPositionSetting; + namespace ILSOS_PrismaticGun.Views.Recipe { internal class UCMainRecipeViewModel : NotifyPropertyChangedBase, IRecipeViewModel diff --git a/Machines/ILSOS_PrismaticScanner/EquipmentSetup.cs b/Machines/ILSOS_PrismaticScanner/EquipmentSetup.cs index 4005908..41e7407 100644 --- a/Machines/ILSOS_PrismaticScanner/EquipmentSetup.cs +++ b/Machines/ILSOS_PrismaticScanner/EquipmentSetup.cs @@ -251,6 +251,7 @@ namespace ILSOS_PrismaticScanner { register(CommonRecipeIds.ScannerObjectTeaching, new ScannerObjectTeachingRecipe(), (id, item) => new UCScannerObjectTeaching(AuroraEnv)); + base.RegisterRecipes(register); } diff --git a/WeldingComponents/WeldingCommon/CommonEquipmentSetup.cs b/WeldingComponents/WeldingCommon/CommonEquipmentSetup.cs index 8731c1b..2783f57 100644 --- a/WeldingComponents/WeldingCommon/CommonEquipmentSetup.cs +++ b/WeldingComponents/WeldingCommon/CommonEquipmentSetup.cs @@ -1,10 +1,7 @@  using Aurora; using Aurora.Api; -// 추가 - Aurora.Api.Device 명시 -using AuroraDevice = Aurora.Api.Device; using Aurora.Api.Manager; - using Aurora.View; using AuroraChiller; using AuroraIO; @@ -21,6 +18,7 @@ using System.Reactive.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; +using VisionCommon; using WeldingCommon.Alarm; using WeldingCommon.Recipes; using WeldingCommon.Sequences; @@ -29,6 +27,8 @@ using WeldingCommon.Utils; using WeldingCommon.Views; using WeldingCommon.Views.DoorInterlock; using WeldingCommon.Vision.Factory; +// 추가 - Aurora.Api.Device 명시 +using AuroraDevice = Aurora.Api.Device; @@ -255,11 +255,23 @@ namespace WeldingCommon // DataContext = new LaserScannerTeachingViewModel(AuroraEnv, new LaserScannerTeachingToolboxViewModel(AuroraEnv)) // }); + // 26.04.13 Gun에 있던 것 Common으로 옮기기 + register(CommonRecipeIds.StageAMainRecipe, new MainRecipe(), + (recipe, item) => new UCMainRecipe() + { + DataContext = new UCMainRecipeViewModel(AuroraEnv, recipe, item, CommonRecipeIds.StageAMainRecipe) + }); + VisionFactory.RegisterRecipe(register); } public virtual void RegisterSequences(SequenceRegister register) { + #region Gun 시퀸스 + + #endregion + + VisionFactory.RegisterSequences(AuroraEnv, register); } @@ -269,6 +281,7 @@ namespace WeldingCommon public virtual void RegisterSettings(SettingRegister register) { + register(CommonSettingIds.SystemParameter, new SystemParameter()); register(CommonSettingIds.LaserPowerCalParam, new LaserPowerCalParam()); register(CommonSettingIds.Sequence, new SequenceSetting()); @@ -276,6 +289,16 @@ namespace WeldingCommon register(CommonSettingIds.RmsDatas, new SettingRmsDataList()); //register(CommonSettingIds.UploadDatas, new SettingUploadDataList()); + #region 26.04.13 Gun 세팅 + var Setting = AuroraEnv.SettingEntry[CommonSettingIds.LaserPowerCalParam] as LaserPowerCalParam; + Setting.Initialize(Setting.PowerCalibrationCenterBeamCSVFile, Setting.PowerCalibrationRingBeamCSVFile); + + register(CommonSettingIds.TeachingPos, new WeldingCommon.Settings.TeachingPositionSetting()); + + register(CommonSettingIds.ManualLaser, new WeldingCommon.Settings.ManualLaserSetting()); + #endregion + + VisionFactory.RegisterSetting(AuroraEnv, register); } diff --git a/WeldingComponents/WeldingCommon/Devices/ACS/ScannerACS.cs b/WeldingComponents/WeldingCommon/Devices/ACS/ScannerACS.cs index a7fa9b9..0cb101b 100644 --- a/WeldingComponents/WeldingCommon/Devices/ACS/ScannerACS.cs +++ b/WeldingComponents/WeldingCommon/Devices/ACS/ScannerACS.cs @@ -100,6 +100,8 @@ namespace WeldingCommon.Devices.ACS // ── 구현 ────────────────────────────────────────────────────────────────── public partial class ScannerACS : ACSDevice, IScannerACS { + //IsReachedTeachingPosition + private ACSDeviceSetting _setting; // Scanner는 Stage X (X2) 1축만 사용 @@ -605,5 +607,23 @@ namespace WeldingCommon.Devices.ACS } bool IScannerACS.IsActivated() => IsActivated; + + // 왜 없앴지.. 26.04.13 + internal bool IsReachedTeachingPosition(eTeachingPosition targetPos) + { + switch (targetPos) + { + case eTeachingPosition.Load: + return _motorVariable.IsLoadPosition; + case eTeachingPosition.UnLoad: + return _motorVariable.IsUnloadPosition; + case eTeachingPosition.SafetyPosition: + return _motorVariable.IsSafetyPosition; + case eTeachingPosition.StageWeldingStartPos: + return _motorVariable.IsWeldingStartPosition; + default: + return false; + } + } } } \ No newline at end of file diff --git a/WeldingComponents/WeldingCommon/EquipDefCommon.cs b/WeldingComponents/WeldingCommon/EquipDefCommon.cs index 802e3cb..1082caa 100644 --- a/WeldingComponents/WeldingCommon/EquipDefCommon.cs +++ b/WeldingComponents/WeldingCommon/EquipDefCommon.cs @@ -1,4 +1,8 @@ -namespace WeldingCommon +using System; +using System.Collections.Generic; +using WeldingCommon.Sequences; + +namespace WeldingCommon { public enum eWorkingPosition { @@ -91,12 +95,25 @@ public const string RmsDatas = "RmsDatas"; public const string Sequence = "Sequence"; + + #region 26.04.13 Gun의 Def 상수 모음 + public const string TeachingPos = "TeachingPos"; + public const string ACS = "ACS"; + public const string LineShotInLinesSetting = "LineShotInLinesSetting"; + + public const string ManualLaser = "LineShotInLines"; + public const string ALineShotInLines = "ALineShotInLines"; + public const string BLineShotInLines = "BLineShotInLines"; + public const string OneShot = "OneShot"; + #endregion } public class CommonRecipeIds { //public const string LaserScannerTeaching = "LaserScannerTeaching"; public const string ScannerObjectTeaching = "ScannerObjectTeaching"; + // 26.04.13 Scanner 프로젝트 Recipe에 StageAMainRecip 추가 + public const string StageAMainRecipe = "StageAMainRecipe"; } public class CommonModelIds @@ -125,8 +142,18 @@ public const string AJINStageMotorZ = "AJINStageMotorZ"; #region - public const string AxisX2 = "AxisX2"; // 26.04.06 추가 + public const string ACS = "ACS"; // 26.04.06 추가 + + public const string AxisX1 = "AxisX1"; + public const string AxisX2 = "AxisX2"; // 26.04.06 추가 + public const string AxisY1 = "AxisY1"; + public const string AxisY2 = "AxisY2"; + + // Ajin Motor + public const string AxisZ = "AxisZ"; + + public const string TeachingPos = "TeachingPos"; #endregion } @@ -178,6 +205,20 @@ public const string AlarmMonitor = "AlarmMonitor"; public const string SeqAutoRun = "SeqAutoRun"; + + #region 26.04.13 Gun 시퀸스 + public const string SeqLoadCellStageA = "SeqLoadCellStageA"; + + public const string SeqWeldingCellStageA = "SeqWeldingCellStageA"; + + public const string TargetMoveSequenceStageA = "TargetMoveSequenceStageA"; + + public const string TeachingMoveSequenceStageA = "TeachingMoveSequenceStageA"; + + public const string SplitLine = "SplitLine"; + public const string MotorInit = "MotorInit"; + public const string OneShot = "OneShot"; + #endregion } public class EquipEvent @@ -221,4 +262,37 @@ public const string StartMain = "Start Main"; public const string ScreenCapture = "Screen Capture"; } + + // 26 .04.13 + public class CommonMotorIds + { + public const string AxisX1 = "AxisX1"; + public const string AxisX2 = "AxisX2"; + public const string AxisY1 = "AxisY1"; + public const string AxisY2 = "AxisY2"; + + // Ajin Motor + public const string AxisZ = "AxisZ"; + + public enum eMotorIdx + { + // ACS Motor + AxisX1, + AxisY1, + AxisX2, + AxisY2, + AxisZ + } + + public static List GetMotorList() => new List(Enum.GetNames(typeof(eMotorIdx))); + + + } + + // 26.04.13 + public enum eYAxisType + { + Y1, + Y2 + } } diff --git a/WeldingComponents/WeldingCommon/Process/Gun/CellState.cs b/WeldingComponents/WeldingCommon/Process/Gun/CellState.cs new file mode 100644 index 0000000..f56c256 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Process/Gun/CellState.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WeldingCommon; + +namespace WeldingCommon.Process +{ + public interface ICellState + { + void Changed(); + } + + public class NotEnteredState : ICellState + { + public NotEnteredState() { + Changed(); + } + public void Changed() + { + Status.SetWorkingPosition(eWorkingPosition.NONE); + } + } + + public class LoadingCompState : ICellState + { + public LoadingCompState() + { + Changed(); + } + public void Changed() + { + Status.SetWorkingPosition(eWorkingPosition.LOADING_CELL); + } + } + + public class WeldingCompState : ICellState + { + public WeldingCompState() + { + Changed(); + } + public void Changed() + { + Status.SetWorkingPosition(eWorkingPosition.EXECUTING_WELD); + } + } + public class UnloadingCompState : ICellState + { + public UnloadingCompState() + { + Changed(); + } + public void Changed() + { + Status.SetWorkingPosition(eWorkingPosition.UNLOADING_CELL); + } + } +} diff --git a/WeldingComponents/WeldingCommon/Process/Gun/PalletInfo.cs b/WeldingComponents/WeldingCommon/Process/Gun/PalletInfo.cs new file mode 100644 index 0000000..ecd9248 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Process/Gun/PalletInfo.cs @@ -0,0 +1,101 @@ +using Aurora; +using Aurora.View; +using WeldingCommon.Device; // 수정 +using System; +using System.Collections.Generic; +using System.Windows; + +namespace WeldingCommon.Process +{ + // UI에서도 쓸 곳이 많을 것 같긴한데.. 일단 추가 + public enum eStage + { + A, + B, + } + public enum ePalletState + { + NotEntered, + // 실물 CELL 있음 + LoadingComp, + Welding, // 저장이 필요한 상태는 아니고, 그냥 UI용으로 사용하면 될듯함 + WeldingComp, + // 실물 CELL 없음 + UnloadingComp, + } + public class PalletInfo : NotifyPropertyChangedBase ,ICloneable + { + public WeldingDataForPrismaticGun weldingData { get => _weldingData; set => SetProperty(ref _weldingData, value); } + private WeldingDataForPrismaticGun _weldingData = new WeldingDataForPrismaticGun(); + public eStage WeldingStage { get => _WeldingStage; set => SetProperty(ref _WeldingStage, value); } + private eStage _WeldingStage; + public ePalletState palletState { get => _palletState; set => SetProperty(ref _palletState, value); } + private ePalletState _palletState; + public event EventHandler PalletStateChanged; + + + #region PLC Cell Data + + #endregion + //private PLCControllerPrismaticGun _plc; + public PalletInfo() + { + //_plc = Application.Current.AuroraEnv().DeviceManager[DeviceIds.PLCDevice] as PLCControllerPrismaticGun; + WeldingStage = eStage.A; + Clear(); + } + + public void SetState(ePalletState palletState) + { + if (this.palletState == palletState) + return; + + this.palletState = palletState; + PalletStateChanged?.Invoke(this, palletState); + } + public bool PalletInfoLoadToPLC() + { + //weldingData.CellId = _plc.CellId(WeldingStage); + //weldingData.LotId = _plc.LotId(); + //weldingData.IsCellExist = _plc.ExistCell(WeldingStage); + //weldingData.IsRework = _plc.ReworkCell(WeldingStage); + //weldingData.IsAlreadyWelding = _plc.AlreadyWeldingCell(WeldingStage); + //weldingData.CellNo = _plc.CellNo(WeldingStage); + //weldingData.NgJudge = _plc.CellJudgeNG(WeldingStage); + + weldingData.LaserWorkComplete = weldingData.IsCellExist; + //_plc.WriteLaserWorkComplete(WeldingStage, weldingData.LaserWorkComplete); + return true; + } + + public bool PalletInfoSendToPLC() + { + //_plc.WriteCellJudgeNG(WeldingStage, weldingData.NgJudge); + //_plc.WriteCellNo(WeldingStage, weldingData.CellNo); + + weldingData.LaserWorkComplete = false; + //_plc.WriteLaserWorkComplete(WeldingStage, weldingData.LaserWorkComplete); + //_plc.UploadReportDatas(weldingData.UploadProcessDatas); + + return true; + } + public void Clear() + { + palletState = ePalletState.NotEntered; + weldingData.Clear(); + } + public object Clone() + { + var palletInfo = new PalletInfo(); + palletInfo.palletState = palletState; + palletInfo.weldingData = weldingData.Clone() as WeldingDataForPrismaticGun; + palletInfo.WeldingStage = WeldingStage; + return palletInfo; + } + + public override string ToString() + { + return $"Pallet State({Enum.GetName(typeof(ePalletState), palletState)}) >> Lot Id({weldingData.LotId}) Cell Id({weldingData.CellId}) >> Cell Exist({weldingData.IsCellExist}) >> NG({weldingData.NgJudge > 0}) : {weldingData.NgReason} ## "; + } + } +} diff --git a/WeldingComponents/WeldingCommon/Process/Gun/ProcessManager.cs b/WeldingComponents/WeldingCommon/Process/Gun/ProcessManager.cs new file mode 100644 index 0000000..2e06ccf --- /dev/null +++ b/WeldingComponents/WeldingCommon/Process/Gun/ProcessManager.cs @@ -0,0 +1,302 @@ +using Aurora; +using Aurora.Api; +using Aurora.Util.HislogPlus; +using Aurora.View; +using AuroraLaser; +using DB; +using Hermes.Functional; +using WeldingCommon.Alarm; +using WeldingCommon.Device; +using WeldingCommon.Device.ACS; +using WeldingCommon.Process; +using WeldingCommon.Process.Services.History; +using WeldingCommon.Tools; // 26.04.13 +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Configuration; +using System.Dynamic; +using System.IO; +using System.Linq; +using System.Reactive.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Documents; + +using WeldingCommon; +using WeldingCommon.Devices; +using WeldingCommon.Popup; +using WeldingCommon.Sequences.Main; +using WeldingCommon.Settings; +using WeldingCommon.Utils; +namespace WeldingCommon +{ + public class ProcessManager + { + private static ProcessManager _Instance; + public static ProcessManager Instance { + get { + if (_Instance is null) { + _Instance = new ProcessManager(); + } + return _Instance; + } + } + + private static DualLogger _Log = new DualLogger(); + + private IAuroraEnvironment _env; + private Laser _laser; + public PalletInfo PalletInStageA { get; set; } + public PalletInfo PalletInStageB { get; set; } + + public IHistoryReader HistoryReader { get; private set; } + private IHistoryWriter _historyWriter; + + private static CsvLogger CsvLogStageA; + private static CsvLogger CsvLogStageB; + + private object _lock = new object(); + public bool StopRequest { + get { + lock(_lock) + return _StopRequest; + } + private set { + lock(_lock) + _StopRequest = value; + } + } + private bool _StopRequest; + public ProcessManager() + { + _Log.AddLogger("ProcessManager", "StageA"); + _Log.AddLogger("ProcessManager", "StageB"); + } + + public void Init(IAuroraEnvironment env) + { + _env = env; + //_plc = env.DeviceManager[CommonDeviceIds.PLCDevice] as PLCControllerPrismaticGun; + //_laser = env.DeviceManager[CommonDeviceIds.Laser] as Laser; + + //env.EventObservable.AsObservable(CommonEventIds.EVENT_AUTO_RUN_START_REQUEST) + // .ObserveOnDispatcher() + // .Subscribe(x => { + // AutoRunStart(); + // _Log.W("PLC Request Auto Run"); + + // }); + + //// PLC Stop - 상태감시 필요 (Cycle Stop) + //env.EventObservable.AsObservable(CommonEventIds.EVENT_AUTO_RUN_STOP_REQUEST) + // .ObserveOnDispatcher() + // .Subscribe(x => { + // _Log.E("PLC Request Auto Run Cycle Stop!!!!"); + // CycleStop(); + // }); + + //// Cell History + //var historyServ = new CellHistoryService(maxCount: 50, pumpMs: 100); + //_historyWriter = historyServ as IHistoryWriter; + //HistoryReader = historyServ as IHistoryReader; + + //var setting = _env.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter; + //CsvLogStageA = new CsvLogger(Path.Combine(setting.CellHistoryFolderPath, "StageA"), "StageA_CellInfo"); + //CsvLogStageB = new CsvLogger(Path.Combine(setting.CellHistoryFolderPath, "StageB"), "StageB_CellInfo"); + + // Pallet Register + RegistrySerializer.Init(); + LoadRegistryData(); + } + + private void SaveRegistryData(eStage stage, PalletInfo cell) + { + RegistrySerializer.SaveToRegistry("PalletInfo", cell); + + Thread.Sleep(50); + } + private void LoadRegistryData() + { + PalletInStageA = RegistrySerializer.LoadFromRegistry("PalletInfo"); + } + + public bool LoadingComplete(PalletInfo cell) + { + cell.SetState(ePalletState.LoadingComp); + + if (Status.EquipmentStatus == eEqpStatus.Auto) + SaveRegistryData(cell.WeldingStage, cell); + + _Log.W($"{cell.ToString()} Load Complete", cell.WeldingStage); + return true; + } + public void WeldingStart(PalletInfo cell) + { + // 저장은 하지 않는다. 웰딩중에 끊기면 배출함 + cell.SetState(ePalletState.Welding); + cell.weldingData.WeldingStartTime = DateTime.Now; + + if (Status.EquipmentStatus == eEqpStatus.Auto) + SaveRegistryData(cell.WeldingStage, cell); + + _Log.W($"{cell.ToString()} Welding Start", cell.WeldingStage); + } + public bool WeldingComplete(PalletInfo cell) + { + // 메뉴얼은 카운팅이 안됨 + if (cell.weldingData.TotalProduct < uint.MaxValue && cell.weldingData.IsLaserOn) + cell.weldingData.TotalProduct++; + + if (cell.weldingData.TodayProduct < uint.MaxValue && cell.weldingData.IsLaserOn) + cell.weldingData.TodayProduct++; + + cell.SetState(ePalletState.WeldingComp); + cell.weldingData.WeldingEndTime = DateTime.Now; + + if (Status.EquipmentStatus == eEqpStatus.Auto) + SaveRegistryData(cell.WeldingStage, cell); + + // 히스토리 파일 저장 + if (cell.WeldingStage is eStage.A) + CsvLogStageA.WriteLineCellData(cell); + else + CsvLogStageB.WriteLineCellData(cell); + + _Log.W($"{cell.ToString()} Welding Complete", cell.WeldingStage); + + return true; + } + + public bool UnloadingComplete(PalletInfo cell) + { + cell.SetState(ePalletState.UnloadingComp); + + if (Status.EquipmentStatus == eEqpStatus.Auto) + SaveRegistryData(cell.WeldingStage, cell); + + // 일단 메뉴얼도 히스토리로 남기도록 함 + _historyWriter.Append(cell.WeldingStage, cell.weldingData.Clone() as WeldingDataForPrismaticGun); + + _Log.W($"{cell.ToString()} Unload Complete", cell.WeldingStage); + + return true; + } + public bool PalletClear(eStage stage) + { + if(stage is eStage.A) { + PalletInStageA.Clear(); + SaveRegistryData(stage, PalletInStageA); + } else { + PalletInStageB.Clear(); + SaveRegistryData(stage, PalletInStageB); + } + + return true; + } + + #region Welding Enable >> Stage 두개 다 사용못하는 경우 알람 발생을 하기위한 플래그.. 이렇게 하면 복잡한데 일단 필요 + private bool _enableLaserUse = true; + public bool IsEnableLaserUse() + { + lock (_lock) { + return _enableLaserUse; + } + } + public void EnableLaserUse(bool enable) + { + lock (_lock) { + _enableLaserUse = enable; + } + } + #endregion + + #region Cycle Stop을 하기 위한 동작 + private bool autoStartStageA = false; + private bool autoStartStageB = false; + internal void SetAutoPrepare(eStage stage, bool on) + { + lock (_lock) + { + if (stage is eStage.A) + autoStartStageA = on; + else + autoStartStageB = on; + + _Log.I($"Stage {Enum.GetName(typeof(eStage), stage)} [Prepare > {on}]", stage); + + if (!autoStartStageA && !autoStartStageB) + { + //_plc.WriteBit(eBitOutput.PC_AUTO_STATUS, false); + //_plc.WriteBit(eBitOutput.PC_AUTO_COMPLETE, false); + //_plc.WriteBit(eBitOutput.PC_MANUAL_COMPLETE, true); + Status.SetStatus(eEqpStatus.Manual); + _laser.LaserOff(); + _Log.W($"Run Stop >> Laser Off && Manual Change"); + } + } + } + + internal bool IsAutoPrepare() + { + lock (_lock) { + if (autoStartStageA && autoStartStageB) { + //_plc.WriteBit(eBitOutput.PC_AUTO_STATUS, true); + //_plc.WriteBit(eBitOutput.PC_AUTO_COMPLETE, true); + //_plc.WriteBit(eBitOutput.PC_MANUAL_COMPLETE, false); + Status.SetStatus(eEqpStatus.Auto); + _Log.W($"Run Prepare OK"); + return true; + } + } + return false; + } + #endregion + + internal void AutoStart(bool on) + { + if (on) { + //if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].RunState == SequenceRunState.Running) + // _env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].Stop(); + //if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].RunState == SequenceRunState.Running) + // _env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].Stop(); + + StopRequest = false; + //EnableLaserUse(true); + //_laser.LaserOn(); + _Log.W($"Laser On Start!!!"); + + // 수정필요 Jeongin + //_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].Start(); + //_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].Start(); + _Log.W($"Auto Sequence Start"); + } else { + //if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].RunState == SequenceRunState.Running) + // _env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].Stop(); + //if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].RunState == SequenceRunState.Running) + // _env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].Stop(); + + //_laser.LaserOff(); + _Log.W($"Auto Sequence Stop"); + } + } + public async void AutoRunStart() + { + bool shouldStop = await TimerMessageBox.ShowAsync(Application.Current.MainWindow, "자동 시작", "자동 운전을 시작하시겠습니까?", true, 5000); + if (!shouldStop) + return; + + AutoStart(true); + } + internal void CycleStop() + { + // 용접중이면, 정지 신호만 주고 정상 시퀀스 종료를 준다 + if (PalletInStageA.palletState == ePalletState.Welding) { + _Log.E($"{PalletInStageA.ToString()} CycleStop OK!! State is welding", eStage.A); + StopRequest = true; + } + } + } +} diff --git a/WeldingComponents/WeldingCommon/Process/Gun/SequenceManagerForMainWelder.cs b/WeldingComponents/WeldingCommon/Process/Gun/SequenceManagerForMainWelder.cs new file mode 100644 index 0000000..4cbf84d --- /dev/null +++ b/WeldingComponents/WeldingCommon/Process/Gun/SequenceManagerForMainWelder.cs @@ -0,0 +1,122 @@ +using Aurora; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WeldingCommon.Devices; +using WeldingCommon; +using Aurora.Api; +using WeldingCommon.Sequences; +using WeldingCommon.Sequences; +using WeldingCommon.Sequences.SubSequence.StageA; +using System.Threading; +using System.Diagnostics; // Process.Start + +namespace WeldingCommon.Process +{ + // 비동기 시퀀스를 사용하기 때문에... 클래스 객체가 여러개 필요함 + public class SequenceManagerForMainWelder + { + private static SequenceManagerForMainWelder _Instance; + public static SequenceManagerForMainWelder Instance { + get { + if (_Instance is null) { + _Instance = new SequenceManagerForMainWelder(); + } + return _Instance; + } + } + + private IAuroraEnvironment _env; + + //public SeqTeachingPosMove TeachingPosSequenceA { get; private set; } + //public SeqTeachingPosMove TeachingPosSequenceB { get; private set; } + + //public SeqAutoRunPrismaticGun MainSequence { get; private set; } + //public SeqLoadCell LoadCellSequence { get; private set; } + //public SeqLoadCell LoadCellSequenceB { get; private set; } + //public SeqWeldingCell WeldingCellSequenceA{ get; private set; } + //public SeqWeldingCell WeldingCellSequenceB{ get; private set; } + //public SeqUnloadCell UnloadingCellSequenceA { get; private set; } + //public SeqUnloadCell UnloadingCellSequenceB { get; private set; } + + //public SeqAutoRunPrismaticGunType MainSequenceTest { get; private set; } + + + public void Init(IAuroraEnvironment env) + { + _env = env; + //TeachingPosSequenceA = new SeqTeachingPosMove(); + //TeachingPosSequenceB = new SeqTeachingPosMove(); + + //MainSequence = new SeqAutoRunPrismaticGun(); + //LoadCellSequence = new SeqLoadCell(); + //LoadCellSequenceB = new SeqLoadCell(); + //WeldingCellSequenceA = new SeqWeldingCell(); + //WeldingCellSequenceB = new SeqWeldingCell(); + //UnloadingCellSequenceA = new SeqUnloadCell(); + //UnloadingCellSequenceB = new SeqUnloadCell(); + + //MainSequenceTest = new SeqAutoRunPrismaticGunType(); + } + + public void RegisterSequence(IAuroraEnvironment aurora, SequenceRegister register) + { + //register(SequenceIds.TargetMoveSequenceStageA, SeqTargetPosMoveStageA.Builder()); + //register(SequenceIds.TargetMoveSequenceStageB, SeqTargetPosMoveStageB.Builder()); + + // Main Sequence는 하나만 사용 + register(CommonSequenceIds.TeachingMoveSequenceStageA, SeqTeachingPosMoveStageA.Builder()); + //register(SequenceIds.TeachingMoveSequenceStageB, SeqTeachingPosMoveStageB.Builder()); + + //Process Sequence + //register(SequenceIds.SeqAutoRunPrismaticGunStageA, SeqAutoRunPrismaticGunStageA.Builder()); + //register(SequenceIds.SeqAutoRunPrismaticGunStageB, SeqAutoRunPrismaticGunStageB.Builder()); + + //register(SequenceIds.SeqLoadCellStageA, SeqLoadCellStageA.Builder()); + //register(SequenceIds.SeqLoadCellStageB, SeqLoadCellStageB.Builder()); + + register(CommonSequenceIds.SeqWeldingCellStageA, SeqWeldingCellStageA.Builder()); + //register(SequenceIds.SeqWeldingCellStageB, SeqWeldingCellStageB.Builder()); + + //register(SequenceIds.SeqUnloadCellStageA, SeqUnloadCellStageA.Builder()); + //register(SequenceIds.SeqUnloadCellStageB, SeqUnloadCellStageB.Builder()); + + //register(SequenceIds.PLCRequest, SeqAutoStart.Builder()); + + + //Monitoring + //register(CommonSequenceIds.AlarmMonitor, SeqAlarmMonitor.Builder()); + //register(SequenceIds.StatusMonitor, SeqStatusMonitor.Builder()); + //register(CommonSequenceIds.PLCMonitor, PLCMonitor.Builder()); + + // Manual or Maint + register(CommonSequenceIds.OneShot, SeqOneShot.Builder()); + register(CommonSequenceIds.SplitLine, SeqSplitLine.Builder()); + register(CommonSequenceIds.MotorInit, SeqMotorInit.Builder()); + } + + public bool CanExcuteLaserSequence() + { + if (_env.SequenceEntry[CommonSequenceIds.OneShot].RunState != SequenceRunState.Idle) + return false; + else if (_env.SequenceEntry[CommonSequenceIds.SplitLine].RunState != SequenceRunState.Idle) + return false; + else if (_env.SequenceEntry[CommonSequenceIds.SeqWeldingCellStageA].RunState != SequenceRunState.Idle) + return false; + + return true; + } + + public bool Terminate() + { + //_env.SequenceEntry[CommonSequenceIds.AlarmMonitor].Stop(); + //_env.SequenceEntry[SequenceIds.StatusMonitor].Stop(); + //_env.SequenceEntry[CommonSequenceIds.PLCMonitor].Stop(); + + Thread.Sleep(200); + return true; + } + } +} diff --git a/WeldingComponents/WeldingCommon/Process/Gun/Services/History/CellHistoryService.cs b/WeldingComponents/WeldingCommon/Process/Gun/Services/History/CellHistoryService.cs new file mode 100644 index 0000000..ee60873 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Process/Gun/Services/History/CellHistoryService.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WeldingCommon.Data.Services.History; + +namespace WeldingCommon.Process.Services.History +{ + public sealed class CellHistoryService : IHistoryWriter, IHistoryReader, IDisposable + { + private readonly HistoryService _core; + + public CellHistoryService(int maxCount = 50, int pumpMs = 100) + { + _core = new HistoryService(maxCount, pumpMs); + + _ = _core.GetHistory(eStage.A); + _ = _core.GetHistory(eStage.B); + } + + public ReadOnlyObservableCollection HistoryA => _core.GetHistory(eStage.A); + public ReadOnlyObservableCollection HistoryB => _core.GetHistory(eStage.B); + + public void Append(eStage stage, T snapshot) => _core.Append(stage, snapshot); + public void Clear(eStage stage) => _core.Clear(stage); + + public void Dispose() => _core.Dispose(); + } +} diff --git a/WeldingComponents/WeldingCommon/Process/Gun/Services/History/IHistoryReader.cs b/WeldingComponents/WeldingCommon/Process/Gun/Services/History/IHistoryReader.cs new file mode 100644 index 0000000..2276315 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Process/Gun/Services/History/IHistoryReader.cs @@ -0,0 +1,10 @@ +using System.Collections.ObjectModel; + +namespace WeldingCommon.Process.Services.History +{ + public interface IHistoryReader + { + ReadOnlyObservableCollection HistoryA { get; } + ReadOnlyObservableCollection HistoryB { get; } + } +} diff --git a/WeldingComponents/WeldingCommon/Process/Gun/Services/History/IHistoryWriter.cs b/WeldingComponents/WeldingCommon/Process/Gun/Services/History/IHistoryWriter.cs new file mode 100644 index 0000000..ff18dab --- /dev/null +++ b/WeldingComponents/WeldingCommon/Process/Gun/Services/History/IHistoryWriter.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WeldingCommon.Process.Services.History +{ + public interface IHistoryWriter + { + void Append(eStage stage, T snapshot); + void Clear(eStage stage); + } +} diff --git a/WeldingComponents/WeldingCommon/Process/Gun/WeldingDataForPrismaticGun.cs b/WeldingComponents/WeldingCommon/Process/Gun/WeldingDataForPrismaticGun.cs new file mode 100644 index 0000000..1bb77b4 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Process/Gun/WeldingDataForPrismaticGun.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using WeldingCommon.Data; + +namespace WeldingCommon.Process +{ + public enum JudgeType + { + NONE = 0, + CAP_PRESS = 1001, + HEIGHT_MEASURE = 1003, + STAGE_A_WELDING = 1004, + STAGE_B_WELDING = 1005, + OCT_MEASURE, + } + public class WeldingDataForPrismaticGun : WeldingData, ICloneable + { + public WeldingDataForPrismaticGun() + { + Clear(); + } + public override void Clear() + { + base.Clear(); + CellNo = -1; + IsCellExist = false; + IsLaserOn = false; + LaserWorkComplete = false; + IsRework = false; + IsAlreadyWelding = false; + NgJudge = (int)JudgeType.NONE; + HeightMeasurements.Clear(); + } + public int CellNo { get; set; } + public bool IsCellExist { get; set; } = false; + public bool IsLaserOn { get; set; } = false; + public bool LaserWorkComplete { get; set; } = false; + public bool IsRework { get; set; } = false; + public bool IsAlreadyWelding { get; set; } = false; + public ObservableCollection HeightMeasurements { get; set; } = new ObservableCollection(); + + // PLC에서 정의되지 않은 정보를 줄 수도 있어서.. Enum으로 생성하지 않음 + public int NgJudge { get => _NgJudge; set => SetProperty(ref _NgJudge, value); } + private int _NgJudge; + + public string NgReason { + get { + if (Enum.IsDefined(typeof(JudgeType), NgJudge)) + return Enum.GetName(typeof(JudgeType), NgJudge); + else + return $"{NgJudge}"; + } + } + + public object Clone() + { + var newItem = new WeldingDataForPrismaticGun(); + + newItem.CellNo = CellNo; + newItem.IsCellExist = IsCellExist; + newItem.IsLaserOn = IsLaserOn; + newItem.LaserWorkComplete = LaserWorkComplete; + newItem.IsRework = IsRework; + newItem.IsAlreadyWelding = IsAlreadyWelding; + newItem.NgJudge = NgJudge; + + newItem.AutoRunStartTime = AutoRunStartTime; + newItem.LoadStartTime = LoadStartTime; + newItem.WeldingStartTime = WeldingStartTime; + newItem.WeldingEndTime = WeldingEndTime; + newItem.UnloadStartTime = UnloadStartTime; + newItem.WeldingSpanTimeMilliseconds = WeldingSpanTimeMilliseconds; + newItem.TodayProduct = TodayProduct; + newItem.TotalProduct = TotalProduct; + newItem.CellId = CellId; + newItem.LotId = LotId; + newItem.LBAD_Judge = LBAD_Judge; + newItem.LDD_Judge = LDD_Judge; + newItem.ScannerFiledImage = ScannerFiledImage; + UploadProcessDatas.ForEach(data => newItem.UploadProcessDatas.Add(data.Clone() as PLCReportData)); + return newItem; + } + } +} diff --git a/WeldingComponents/WeldingCommon/Recipes/Gun/MainRecipe.cs b/WeldingComponents/WeldingCommon/Recipes/Gun/MainRecipe.cs new file mode 100644 index 0000000..6db2a2b --- /dev/null +++ b/WeldingComponents/WeldingCommon/Recipes/Gun/MainRecipe.cs @@ -0,0 +1,240 @@ +using Aurora.Api; +using Aurora.Api.Devices; +using Aurora.View; + +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Reactive; +using System.Text; +using System.Threading.Tasks; +#region 26.04.13 +using static WeldingCommon.Recipes.MainRecipe; +using WeldingCommon.Recipes; +#endregion +namespace WeldingCommon.Recipes +{ + public class MainRecipe : NotifyPropertyChangedBase, IRecipeItem, ICloneable + { + public enum eOutType + { + Analog, // V + Interval, // hz + } + public MainRecipe() + { + CurveParam = new LineParameter(); + StraightParam = new LineParameter(); + } + + // Laser Parameter + public LineParameter CurveParam { get; set; } + public LineParameter StraightParam { get; set; } + + // Motion Parameter + public double WeldingAcc { get; set; } + //public double AxisTPosition { get; set; } + public double AxisZPosition { get; set; } + + public ProcessUnit StartPos { get; set; } = new ProcessUnit(); + public ProcessUnit EndPos { get; set; } = new ProcessUnit(); + + public ProcessUnit MarkPos { get; set; } = new ProcessUnit(); + public double MarkVoltage { get; set; } + public int MarkShotTimeMsec { get; set; } + + //Binding된 객체가 []로 호출 시, 최초 데이터를 저장(생성)하지 못함. + //public ObservableCollection Arc { get; set; } = new ObservableCollection(new List(4)); + public ProcessArc Arc1 { get; set; } = new ProcessArc(); + public ProcessArc Arc2 { get; set; } = new ProcessArc(); + public ProcessArc Arc3 { get; set; } = new ProcessArc(); + public ProcessArc Arc4 { get; set; } = new ProcessArc(); + public ObservableCollection Units { get; set; } = new ObservableCollection(new List(8)); + + public bool HeightMeasureSkip { get; set; } + /* + 장변 편차 (인덱스 번호 1번-4번, 5번-8번 편차) + 단변 편차(인덱스 번호 1번-5번, 4번-8번 편차) + 4 3 2 1 + 8 7 6 5 + */ + public double JudgeLimit { get; set; } + public ObservableCollection HeightSensorMeasurePoints { get; set; } = new ObservableCollection(); + + public double LaserOnPosition { get; set; } + //public double LaserOnPositionOffset { get; set; } + //public double LaserOffPosition { get; set; } + //public double LaserOffPositionOffset { get; set; } + //public double RampingOnStartPos { get; set; } + public double RampingOnOverlapDist { get; set; } + public double RampingOnStartPower { get; set; } + public double RampingOffStartPos { get; set; } + public double RampingOffOverlapDist { get; set; } + public double RampingOffEndPower { get; set; } + // Min, Max 고민 필요 + public double N2PressMFC { get; set; } + + // notused Laser + public bool IsReviewMode { get => _IsReviewMode; set => SetProperty(ref _IsReviewMode, value); } + private bool _IsReviewMode; + public bool IsMarkMode { get; set; } = false; + + public YAxisType YAxisUseType { get; set; } + public enum YAxisType + { + Y1, + Y2 + } + + public object Clone() + { + MainRecipe newRecipe = new MainRecipe(); + newRecipe.CurveParam = CurveParam.Clone() as LineParameter; + newRecipe.StraightParam = StraightParam.Clone() as LineParameter; + newRecipe.WeldingAcc = WeldingAcc; + newRecipe.AxisZPosition = AxisZPosition; + newRecipe.StartPos = StartPos.Clone() as ProcessUnit; + newRecipe.EndPos = EndPos.Clone() as ProcessUnit; + newRecipe.MarkPos = MarkPos.Clone() as ProcessUnit; + newRecipe.MarkVoltage = MarkVoltage; + newRecipe.MarkShotTimeMsec = MarkShotTimeMsec; + newRecipe.Arc1 = Arc1.Clone() as ProcessArc; + newRecipe.Arc2 = Arc2.Clone() as ProcessArc; + newRecipe.Arc3 = Arc3.Clone() as ProcessArc; + newRecipe.Arc4 = Arc4.Clone() as ProcessArc; + + for (int i = 0; i < Units.Count; i++) + newRecipe.Units.Add(Units[i].Clone() as ProcessUnit); + + newRecipe.HeightMeasureSkip = HeightMeasureSkip; + newRecipe.JudgeLimit = JudgeLimit; + + for (int i = 0; i < HeightSensorMeasurePoints.Count; i++) + newRecipe.HeightSensorMeasurePoints.Add(HeightSensorMeasurePoints[i].Clone() as HeightMeareUnit); + + newRecipe.LaserOnPosition = LaserOnPosition; + newRecipe.RampingOnOverlapDist = RampingOnOverlapDist; + newRecipe.RampingOnStartPower = RampingOnStartPower; + newRecipe.RampingOffStartPos = RampingOffStartPos; + newRecipe.RampingOffOverlapDist = RampingOffOverlapDist; + newRecipe.RampingOffEndPower = RampingOffEndPower; + newRecipe.N2PressMFC = N2PressMFC; + newRecipe.IsReviewMode = IsReviewMode; + newRecipe.IsMarkMode = IsMarkMode; ; + newRecipe.YAxisUseType = YAxisUseType; + + return newRecipe; + } + /* + var coreRatio = _mainRecipe.StraightParam.StraightCorePowerW / (_mainRecipe.StraightParam.StraightCorePowerW + _mainRecipe.StraightParam.StraightCorePowerW); + var Max = 3000; + var CoreMax = Max * coreRatio; + var StraightVoltage = (_mainRecipe.StraightParam.StraightCorePowerW / CoreMax) * 10; + var CornerVoltage = (_mainRecipe.StraightParam.CornerCorePowerW / CoreMax) * 10; + _mainRecipe.StraightParam.CornerRingPowerW = _mainRecipe.StraightParam.CornerRingPowerW * (1 - coreRatio / coreRatio); + + _laser.SetData(csWriteNodeNo.IW03, (int)coreRatio); +*/ + } +} +public class LineParameter : NotifyPropertyChangedBase, ICloneable +{ + public double ShotTime { get => _ShotTime; set => _ShotTime = value; } + private double _ShotTime; + // Min, Max 고민 필요 + public double Velocity { get; set; } + + #region ACS Output Param + public eOutType OutputType { get => _OutputType; set => _OutputType = value; } + private eOutType _OutputType; + public double Output { get => _Output; set => _Output = value; } + private double _Output; + #endregion + + #region Laser Out Param + public double CorePowerW { get => _CorePowerW; set => SetProperty(ref _CorePowerW, value); } + public double _CorePowerW; + public double RingPowerW { get => _RingPowerW; set => SetProperty(ref _RingPowerW, value); } + public double _RingPowerW; + + public object Clone() + { + LineParameter newItem = new LineParameter(); + newItem.ShotTime = ShotTime; + newItem.Velocity = Velocity; + newItem.OutputType = OutputType; + newItem.Output = Output; + newItem.CorePowerW = CorePowerW; + newItem.RingPowerW = RingPowerW; + return newItem; + } + #endregion +} + +public class ProcessUnit : NotifyPropertyChangedBase, ICloneable +{ + public int Index { get => _Index; set => SetProperty(ref _Index, value); } + private int _Index; + + public double PosX { get => _PosX; set => SetProperty(ref _PosX, value); } + private double _PosX; + + public double PosY { get => _PosY; set => SetProperty(ref _PosY, value); } + private double _PosY; + + public object Clone() + { + ProcessUnit newItem = new ProcessUnit(); + newItem.Index = Index; + newItem.PosX = PosX; + newItem.PosY = PosY; + return newItem; + } +} + +public class ProcessArc : NotifyPropertyChangedBase, ICloneable +{ + public int Index { get => _Index; set => SetProperty(ref _Index, value); } + private int _Index; + + public double Size { get => _Size; set => SetProperty(ref _Size, value); } + private double _Size; + + public object Clone() + { + ProcessArc newItem = new ProcessArc(); + newItem.Index = Index; + newItem.Size = Size; + return newItem; + } +} + +public class HeightMeareUnit : NotifyPropertyChangedBase, ICloneable +{ + public int Index { get => _Index; set => SetProperty(ref _Index, value); } + private int _Index; + + public double PosX { get => _PosX; set => SetProperty(ref _PosX, value); } + private double _PosX; + + public double PosY { get => _PosY; set => SetProperty(ref _PosY, value); } + private double _PosY; + + public object Clone() + { + HeightMeareUnit newItem = new HeightMeareUnit(); + newItem.Index = Index; + newItem.PosX = PosX; + newItem.PosY = PosY; + return newItem; + } + + //public double LoadDirRefBase { get => _LoadDirRefBase; set => SetProperty(ref _LoadDirRefBase, value); } + //private double _LoadDirRefBase; + + //public double UnloadDirRefBase { get => _UnloadDirRefBase; set => SetProperty(ref _UnloadDirRefBase, value); } + //private double _UnloadDirRefBase; +} \ No newline at end of file diff --git a/WeldingComponents/WeldingCommon/Sequences/Calibration/SeqScannerCalibration.cs b/WeldingComponents/WeldingCommon/Sequences/Calibration/SeqScannerCalibration.cs index 724aae8..b794cf3 100644 --- a/WeldingComponents/WeldingCommon/Sequences/Calibration/SeqScannerCalibration.cs +++ b/WeldingComponents/WeldingCommon/Sequences/Calibration/SeqScannerCalibration.cs @@ -431,7 +431,7 @@ namespace WeldingCommon.Sequences // Laser Scanner Calibration인 경우 int visionBitX = (int)(((_CurrentPositionX - _InitParam.MasterPosOffsetX) * 2 - currentX) * _Scanner.Config.ScaleXYFactor); int visionBitY = (int)(((_CurrentPositionY - _InitParam.MasterPosOffsetY) * 2 - currentY) * _Scanner.Config.ScaleXYFactor); - + // 26.04.13 이곳에서 이벤트 발생으로 데이터 전달 var updateDataGridItem = new UpdateDataGridItem(_PositionIndex, (int)visionBitX, (int)visionBitY); context.EventPublisher.Publish(new EventMessage(context.SequenceId, context.SequenceId, updateDataGridItem)); Thread.Sleep(100); diff --git a/WeldingComponents/WeldingCommon/Sequences/Gun/Monitoring/SeqAlarmMonitor.cs b/WeldingComponents/WeldingCommon/Sequences/Gun/Monitoring/SeqAlarmMonitor.cs new file mode 100644 index 0000000..9d87198 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Sequences/Gun/Monitoring/SeqAlarmMonitor.cs @@ -0,0 +1,176 @@ +using ACS.SPiiPlusNET; +using Aurora; +using Aurora.Api; +using Aurora.Framework.Alarm; +using AuroraACS; +using AuroraChiller; +using AuroraIO; +using AuroraLaser; +using AuroraLaser.Trumpf; +using AuroraLaserScanner; +using AuroraLBAD; +using AuroraMotionBoard.Ajin; +using AuroraOCT; +using Hermes.Functional; +using WeldingCommon.Alarm; +using WeldingCommon.Device; +using WeldingCommon.Device.ACS; +using WeldingCommon.Process; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using WeldingCommon; +using WeldingCommon.Alarm; +using WeldingCommon.Devices; +using WeldingCommon.Sequences; +using WeldingCommon.Settings; +using WeldingCommon.Utils; +using WeldingCommon.Devices.ACS; + +namespace WeldingCommon.Sequences.Monitoring +{ + public class SeqAlarmMonitor + { + static readonly Logger Log = new Logger("AlarmMonitoring"); + + const string SEQ_START = "SEQ START"; // 딱 한번 Sequence 진입 시에만 실행될 Node + + const string SEQ_LoopFirst = "SEQ Loop First"; + + public const string CHECK_ALARM_PLC = "Check Alarm PLC"; + public const string CHECK_ALARM_ACS = "Check Alarm ACS"; + public const string CHECK_ALARM_LASER = "Check Alarm Laser"; + public const string CHECK_ALARM_IO = "Check Alarm IO"; + + private static SequenceSetting _SequenceSetting; + + private static Laser _laser; + private static LaserTruFiber _laserCore; + private static ScannerACS _acs; // 26.04.13 + private static ACSMotor _axisX, _axisY1, _axisY2, _axisZ; + + public const int NODE_SLEEP = 100; // msec + + public static SequenceBuilder Builder() + { + SequenceBuilder sb = new SequenceBuilder(1000, true); + + sb.AddAction(SEQ_START, StartNode); + sb.AddDecision(SEQ_LoopFirst, LoopFirstNode); + sb.AddAction(CHECK_ALARM_LASER, CheckAlarmLaser); + sb.AddAction(CHECK_ALARM_IO, CheckAlarmIO); + sb.AddAction(CHECK_ALARM_ACS, CheckAlarmAcs); + + sb.Flows(sb.Init > sb[SEQ_START] > sb[SEQ_LoopFirst] + > sb[CHECK_ALARM_LASER] > sb[CHECK_ALARM_IO] > sb[CHECK_ALARM_ACS] + > sb[SEQ_LoopFirst]); + + sb.Flows(sb[SEQ_LoopFirst] > sb.Final); + + sb.OnStopped(OnStopped); + sb.OnForceError(OnForceError); + + //sb.Draw("SeqAlarmMonitor.pdf"); + + return sb; + + } + + private static SequenceActionResult StartNode(SequenceContext context, string id, SequenceActionResult param) + { + _SequenceSetting = context.Settings[CommonSettingIds.Sequence] as SequenceSetting; + + if (_laser is null) + _laser = context.Devices[CommonDeviceIds.Laser] as Laser; + + _laserCore = _laser.getCore() as LaserTruFiber; + + if (_acs is null) + _acs = context.Devices[CommonDeviceIds.ACS] as ScannerACS; + + if (_axisX is null) + _axisX = context.Devices[CommonMotorIds.AxisX2] as ACSMotor; + + if (_axisY1 is null) + _axisY1 = context.Devices[CommonMotorIds.AxisY1] as ACSMotor; + + if (_axisY2 is null) + _axisY2 = context.Devices[CommonMotorIds.AxisY2] as ACSMotor; + + if (_axisZ is null) + _axisZ = context.Devices[CommonMotorIds.AxisZ] as ACSMotor; + + return SequenceAction.Ok(); + } + + private static string LoopFirstNode(SequenceContext context, string id, ICollection branches, SequenceActionResult param) + { + while (!context.Stopped) { + return CHECK_ALARM_PLC; + } + + Thread.Sleep(NODE_SLEEP); + return SeqNodeIds.FINAL; + } + + private static SequenceActionResult CheckAlarmAcs(SequenceContext context, string id, SequenceActionResult param) + { + if ((_acs.HasHeavyAlarm | _acs.HasLightAlarm) & _acs.IsActivated) { + foreach (var alarm in _acs.HaveAlarmCodes) { + if (alarm != 0) { + if (!AlarmManager.IsOccuredAlarm(alarm)) + Log.E($"{context.AlarmAccured(alarm)}"); + } + } + } + + Thread.Sleep(NODE_SLEEP); + return SequenceAction.Ok(); + } + + private static SequenceActionResult CheckAlarmLaser(SequenceContext context, string id, SequenceActionResult param) + { + #region 26.04.13 잠시 주석처리 + //_laserCore = _laser.getCore() as LaserTruFiber; + //if (_laserCore.GetEStopOpen()) { + // if (!AlarmManager.IsOccuredAlarm(AlarmCode_PrismaticGun.DEVICE_IO_LASER_EMO)) + // Log.E($"{context.AlarmAccured(AlarmCode_PrismaticGun.DEVICE_IO_LASER_EMO)}"); + //} + //if (_laserCore.GetFaultLaser()) { + // if (!AlarmManager.IsOccuredAlarm(AlarmCode_PrismaticGun.DEVICE_LASER_ERROR_MSG)) { + // string alarmCode = $"{Convert.ToString(_laserCore.GetLastMessageCompID(), 16).ToUpper().PadLeft(2, '0')}{Convert.ToString(_laserCore.GetLastMessageCompNum(), 16).ToUpper().PadLeft(2, '0')} {Convert.ToString(_laserCore.GetLastMessageMsgCode(), 16).ToUpper().PadLeft(2, '0')}"; + // string alarmDescription = $" {_laserCore.GetLastMessageShortText()}"; + // Log.E($"{context.AlarmAccured(AlarmCode_PrismaticGun.DEVICE_LASER_ERROR_MSG)} >> code desc {alarmCode + alarmDescription}"); + // } + //} else if (_laserCore.GetMonitoring()) { + // if (!AlarmManager.IsOccuredAlarm(AlarmCode_PrismaticGun.DEVICE_LASER_WARNING_MSG)) { + // string alarmCode = $"{Convert.ToString(_laserCore.GetLastMessageCompID(), 16).ToUpper().PadLeft(2, '0')}{Convert.ToString(_laserCore.GetLastMessageCompNum(), 16).ToUpper().PadLeft(2, '0')} {Convert.ToString(_laserCore.GetLastMessageMsgCode(), 16).ToUpper().PadLeft(2, '0')}"; + // string alarmDescription = $" {_laserCore.GetLastMessageShortText()}"; + // Log.E($"{context.AlarmAccured(AlarmCode_PrismaticGun.DEVICE_LASER_WARNING_MSG)} >> code desc {alarmCode + alarmDescription}"); + // } + //} + //Thread.Sleep(NODE_SLEEP); + + #endregion + return SequenceAction.Ok(); + + + } + private static SequenceActionResult CheckAlarmIO(SequenceContext context, string id, SequenceActionResult param) + { + return SequenceAction.Ok(); + } + + private static void OnStopped(SequenceContext context) + { + } + + private static void OnForceError(SequenceContext context, string arg2) + { + } + } +} diff --git a/WeldingComponents/WeldingCommon/Sequences/Gun/SeqMotorInit.cs b/WeldingComponents/WeldingCommon/Sequences/Gun/SeqMotorInit.cs new file mode 100644 index 0000000..d52dbff --- /dev/null +++ b/WeldingComponents/WeldingCommon/Sequences/Gun/SeqMotorInit.cs @@ -0,0 +1,172 @@ +using ACS.SPiiPlusNET; +using Aurora; +using Aurora.Api; +using Aurora.Api.Devices; +using Aurora.View; +using AuroraACS; +//using AuroraHeightSensor; //26.04.13 잠시 주석 +using AuroraLaser; +using AuroraLaser.Trumpf; +using AuroraMassFlowMeter; +using AuroraMotionBoard.Ajin; +using AuroraOCT.Trumpf; +using Hermes; +using WeldingCommon.Alarm; +using WeldingCommon.Device; +using WeldingCommon.Device.ACS; +using WeldingCommon.Process; +using WeldingCommon.Recipes; +using WeldingCommon.Sequences.SubSequence.StageA; +using WeldingCommon.Settings; +using WeldingCommon.Tools; +using WeldingCommon.Views.Recipes; +using OpenCvSharp.Dnn; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using System.Windows; +using VisionCommon; +using WeldingCommon; +using WeldingCommon.Alarm; +using WeldingCommon.Data; +using WeldingCommon.Sequences; +using WeldingCommon.Settings; +using static AuroraOCT.Trumpf.OCT; +using static WeldingCommon.Devices.PLCController; +using WeldingCommon.Devices.ACS; + + +namespace WeldingCommon.Sequences +{ + class SeqMotorInit + { + static readonly Logger Log = new Logger("MotorInitSequence"); + const int SEQ_TIMEOUT = 120 * 1000; + const int RESET_TIMEOUT = 10 * 1000; + + const int MOTION_TIMEOUT = 10 * 1000; + const int MOTION_INTERVAL = 20; + + const string SEQ_ENTER = "SEQ_ENTER"; + const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; + const string SEQ_ACS_ALARM_RESET = "ACS Alarm Reset"; + const string SEQ_INIT_ACS_AXIS = "Init ACS X,Y Axis"; + const string SEQ_INIT_COMPLETE = "Init Complete"; + + private static ScannerACS _acs; + private static IScannerACS _motion; + + public static SequenceBuilder Builder() + { + SequenceBuilder sb = new SequenceBuilder(1000, true); + + sb.AddAction(SEQ_ENTER, Sequence_Enter); + sb.AddAction(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); + sb.AddAction(SEQ_ACS_ALARM_RESET, ACSAlarmReset); + sb.AddAction(SEQ_INIT_ACS_AXIS, ACSAxisInit); + sb.AddAction(SEQ_INIT_COMPLETE, InitComplete); + + sb.OnStopped(OnStopped); + sb.OnForceError(OnForceError); + + sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_ACS_ALARM_RESET] > sb[SEQ_INIT_ACS_AXIS] > sb[SEQ_INIT_COMPLETE] > sb.Final); + return sb; + } + + private static SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param) + { + if (_motion is null) + _motion = _acs = context.Devices[CommonDeviceIds.ACS] as ScannerACS; + + return SequenceAction.Ok(); + } + + private static SequenceActionResult CheckInitCondition(SequenceContext context, string id, SequenceActionResult param) + { + if (!((_motion as ScannerACS).IsActivated)) { + // 26.04.13 잠시 주석 + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_DEACTIVATED_DISCONNECTED); + //context.PutValue("AlarmMessage", + // $"[ACS activated({(_motion as PrismaticGunACS).IsActivated})]"); + return null; + } + + return SequenceAction.Ok(); + } + + private static SequenceActionResult ACSAlarmReset(SequenceContext context, string id, SequenceActionResult param) + { + Log.V("ACS Alarm Reset Start"); + _motion.ResetAlarm(); + Thread.Sleep(1000); + + var res = context.RetryUntilSuccess(() => !_acs.HasHeavyAlarm & !_acs.HasLightAlarm, RESET_TIMEOUT, MOTION_INTERVAL); + if (res == E2.TIMEOUT) { + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.ACS_AXIS_INITIALIZE_FAIL); //26.04.13 잠시 주석 + context.PutValue("AlarmMessage", "ACS Alarm Reset Fail"); + return null; + } else if (res == E2.CANCELLED) { + context.PutValue("AlarmCode", 0); + context.PutValue("AlarmMessage", "ACS Alarm Reset Cancel"); + return null; + } + Log.V("ACS Alarm Reset End"); + + return SequenceAction.Ok(); + } + + private static SequenceActionResult ACSAxisInit(SequenceContext context, string id, SequenceActionResult param) + { + Log.V($"ACS Init Start"); + _motion.AllAxisHomeStart(); + Thread.Sleep(1000); + + var res = context.RetryUntilSuccess(() => _motion.CheckAllAxisHome(), SEQ_TIMEOUT, MOTION_INTERVAL); + if (res == E2.TIMEOUT) { + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.ACS_AXIS_INITIALIZE_FAIL); // 26.04.13 잠시 주석 + context.PutValue("AlarmMessage", "ACS Axis Home Timeout"); + return null; + } else if (res == E2.CANCELLED) { + context.PutValue("AlarmCode", 0); + context.PutValue("AlarmMessage", "ACS Axis Home Cancel"); + return null; + } + + Log.V($"ACS Init End"); + return SequenceAction.Ok(eTeachingPosition.SafetyPosition); + } + + private static SequenceActionResult InitComplete(SequenceContext context, string id, SequenceActionResult param) + { + MessageBox.Show("전체 초기화 완료"); + MessageUtil.ShowSuccessToast("Initialize Complete", Log); + return SequenceAction.Ok(); + } + + private static void OnStopped(SequenceContext context) + { + var AlarmCode = context.GetValue("AlarmCode"); + if (AlarmCode > 0) + Log.E(context.AlarmAccured(AlarmCode)); + + _motion.AllAxisHomeStop(); + + return; + } + + private static void OnForceError(SequenceContext context, string arg2) + { + var AlarmCode = context.GetValue("AlarmCode"); + if (AlarmCode > 0) + Log.E(context.AlarmAccured(AlarmCode)); + + var message = context.GetValue("AlarmMessage"); + Application.Current.Dispatcher.Invoke(() => { MessageUtil.CreateAndShowMessageDialog("Initialize", message); }); + + _motion.AllAxisHomeStop(); + + return; + } + } +} diff --git a/WeldingComponents/WeldingCommon/Sequences/Gun/SeqOneShot.cs b/WeldingComponents/WeldingCommon/Sequences/Gun/SeqOneShot.cs new file mode 100644 index 0000000..e5a1b3d --- /dev/null +++ b/WeldingComponents/WeldingCommon/Sequences/Gun/SeqOneShot.cs @@ -0,0 +1,172 @@ +using Aurora.Api; +using Aurora.Api.Devices; +using Aurora.Util.HislogPlus; +using Aurora.View; +using AuroraLaser; +using AuroraLaser.Trumpf; +using AuroraMassFlowMeter; +using Hermes; +using Hermes.Collections; +using WeldingCommon.Alarm; +using WeldingCommon.Device.ACS; +using WeldingCommon.Process; +using WeldingCommon.Recipes; +using WeldingCommon.Settings; +using WeldingCommon.Tools; +using WeldingCommon.Views.Recipes; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using WeldingCommon; +using WeldingCommon.Sequences; +using WeldingCommon.Devices.ACS; + +namespace WeldingCommon.Sequences +{ + class SeqOneShot + { + static readonly Logger Log = new Logger("OneShotSequence"); + const string SEQ_ENTER = "SEQ_ENTER"; + const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; + const string SEQ_ONE_SHOT = "OneShot"; + const string SEQ_ONE_SHOT_COMPLETE = "OneShot Sequence Complete"; + private static IScannerACS _motion; + private static Laser _laser; + private static OneShotItem _Item; // 26.04.13 + private static eStage _stage; + + public static bool _LaserIOUse; + + const int MOTION_TIMEOUT = 10 * 1000; + const int WELDING_TIMEOUT = 100 * 1000; + const int MOTION_INTERVAL = 20; + + public static SequenceBuilder Builder() + { + SequenceBuilder sb = new SequenceBuilder(1000, true); + + sb.AddAction(SEQ_ENTER, Sequence_Enter); + sb.AddAction(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); + sb.AddAction(SEQ_ONE_SHOT, OneShot); + sb.AddAction(SEQ_ONE_SHOT_COMPLETE, ProcessComplete); + + sb.OnStopped(OnStopped); + sb.OnForceError(OnForceError); + + sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_ONE_SHOT] > sb[SEQ_ONE_SHOT_COMPLETE] > sb.Final); + + //sb.Draw("SeqOneShot.pdf"); + + return sb; + } + + public static SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param) + { + Log.I("SeqOneShot Start"); + if (_motion is null) + _motion = context.Devices[CommonDeviceIds.ACS] as IScannerACS; + //if (_laser is null) + // _laser = context.Devices[CommonDeviceIds.Laser] as Laser; + + var settingItems = (ManualLaserSetting)param.Param; // 26.04.13 + _Item = settingItems.OneShots; + _LaserIOUse = settingItems.LaserIOUse; + + return SequenceAction.Ok(); + } + + private static SequenceActionResult CheckInitCondition(SequenceContext context, string id, SequenceActionResult param) + { + Log.I("SeqOneShot CheckInitCondition"); + if (!((_motion as ScannerACS).IsActivated)) { + Log.E($"[ACS activated({(_motion as ScannerACS).IsActivated})]"); + return null; + } + + _motion.SetLaserIOUse(_LaserIOUse); + Log.V($"LaserUse({_LaserIOUse})"); + + //if (!(_laser.IsActivated && _laser.GetConnected())) { + // Log.E($"[Laser activated({_laser.IsActivated}) / connected({_laser.GetConnected()})]"); + // context.PutValue("AlarmCode", AlarmCode_PrismaticGun.DEVICE_LASER_DEACTIVATED_DISCONNECTED); + // return null; + //} + + //if (!_laser.GetLaserReady()) { + // _laser.LaserOn(); + + // Log.V($"Laser On"); + // var res = context.RetryUntilSuccess(() => _laser.GetLaserReady(), WELDING_TIMEOUT, MOTION_INTERVAL); + // if (res == E2.TIMEOUT) { + // Log.FuncE("Laser Ready Check Timeout!"); + // context.PutValue("AlarmCode", AlarmCode_PrismaticGun.GET_LASER_READY); + // return null; + // } else if (res == E2.CANCELLED) { + // Log.FuncE("Laser Ready Check Cancel!"); + // context.PutValue("AlarmCode", 0); + // return null; + // } + //} + + Log.V($"Laser Setting Complete"); + return SequenceAction.Ok(); + } + + private static SequenceActionResult OneShot(SequenceContext context, string id, SequenceActionResult param) + { + var _shotTime = _Item.ShotTime; + var _shotPower1 = _Item.ShotPower1; + var _shotPower2 = _Item.ShotPower2; + + _motion.SetLCILserOn(true); + _motion.SetOneShot(_shotTime, _shotPower1, _shotPower2); + Thread.Sleep(500); + + _motion.OneShotStart(); + Log.E(">> OneShot Start"); + Thread.Sleep(500); + + return SequenceAction.Ok(); + } + + private static SequenceActionResult ProcessComplete(SequenceContext context, string id, SequenceActionResult param) + { + var ret = context.RetryUntilSuccess(() => _motion.CheckOneShotComp(), MOTION_TIMEOUT, MOTION_INTERVAL); + if(ret == E2.TIMEOUT) { + Log.E("OneShot Timeout"); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.ACS_ONESHOT_COMP); //26.04.13 잠시 주석 + return null; + } else if(ret == E2.CANCELLED) { + Log.E("OneShot Cancel"); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.ACS_ONESHOT_COMP); // 26.04.13 잠시 주석 + return null; + } + + Log.FuncV(">> OneShot Complete"); + _motion.SetLCILserOn(false); + //_laser.LaserOff(); + Thread.Sleep(500); + return SequenceAction.Ok(); + } + + private static void OnStopped(SequenceContext context) + { + _motion.SetLCILserOn(false); + //_laser.LaserOff(); + MessageUtil.ShowErrorToast(">> Sequence Stop"); + return; + } + + private static void OnForceError(SequenceContext context, string arg2) + { + _motion.SetLCILserOn(false); + //_laser.LaserOff(); + MessageUtil.ShowErrorToast(">> Sequence Fail"); + return; + } + } +} diff --git a/WeldingComponents/WeldingCommon/Sequences/Gun/SeqSplitLine.cs b/WeldingComponents/WeldingCommon/Sequences/Gun/SeqSplitLine.cs new file mode 100644 index 0000000..08ad617 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Sequences/Gun/SeqSplitLine.cs @@ -0,0 +1,360 @@ +using Aurora.Api; +using Aurora.Api.Devices; +using Aurora.Api.Manager; +using Aurora.View; +using AuroraACS; +using AuroraLaser; +using AuroraLaser.Trumpf; +using AuroraMassFlowMeter; +using AuroraMotionBoard.Ajin; +using AuroraOCT.Trumpf; +using Hermes; +using WeldingCommon.Alarm; +using WeldingCommon.Device.ACS; +using WeldingCommon.Process; +using WeldingCommon.Recipes; +using WeldingCommon.Sequences.SubSequence.StageA; +using WeldingCommon.Settings; +using WeldingCommon.Tools; +using OpenCvSharp; +using OpenCvSharp.Dnn; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using VisionCommon; +using WeldingCommon; +using WeldingCommon.Settings; +using static AuroraOCT.Trumpf.OCT; +using WeldingCommon.Devices.ACS; + +namespace WeldingCommon.Sequences +{ + class SeqSplitLine + { + static readonly Logger Log = new Logger("SplitLineSequence"); + const int SLEEP_TIME_MS = 50; + const int SEQ_CHECK_TIMER = 100; + const int SEQ_TIMEOUT = 30 * 1000; + + const int MOTION_TIMEOUT = 10 * 1000; + const int MOTION_INTERVAL = 20; + const int WELDING_TIMEOUT = 30 * 1000; + + const string SEQ_ENTER = "SEQ_ENTER"; + const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; + const string SEQ_CHECK_LINE_COUNT = "Check Line Counting"; + const string SEQ_Z_AXIS_MOVE = "X Axis Moving"; + const string SEQ_ACS_PARAMETER_SET = "ACS Parameter Setting"; + const string SEQ_WELDING_MOTION = "Welding Motion"; + const string SEQ_MOTION_INTERLOCK = "Motion Interlock"; + const string SEQ_LINE_PROCESS_COMPLETE = "SplitSequence Complete"; + + private static ManualLaserSetting _manual; + private static ObservableCollection _data; + private static bool _LaserIOUse; + + private static int LineInLinesCount; + private static int LineInLinesIndex = 0; + + private static MainRecipe _mainRecipe; + + private static ScannerACS _acs; + private static IScannerACS _acsMotion; + private static Laser _laser; + private static LaserTruFiber _laserCore; + private static LaserPowerCalParam _laserCal; + private static ACSMotor _AxisX, _AxisY, _AxisZ; + private static AuroraACS.Speed _spd = AuroraACS.Speed.M; + private static TeachingPositionSetting _setting; + + public static SequenceBuilder Builder() + { + SequenceBuilder sb = new SequenceBuilder(1000, true); + + sb.AddAction(SEQ_ENTER, Sequence_Enter); + sb.AddAction(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); + sb.AddDecision(SEQ_CHECK_LINE_COUNT, CheckLineCount); + sb.AddAction(SEQ_Z_AXIS_MOVE, ZAxisMove); + sb.AddAction(SEQ_ACS_PARAMETER_SET, AcsParameterSetting); + sb.AddAction(SEQ_WELDING_MOTION, WeldingMotion); + + sb.AddAction(SEQ_MOTION_INTERLOCK, MotionInterlock); + sb.AddAction(SEQ_LINE_PROCESS_COMPLETE, LineProcessComplete); + + sb.OnStopped(OnStopped); + sb.OnForceError(OnForceError); + + sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_CHECK_LINE_COUNT]); + + sb.Flows(sb[SEQ_CHECK_LINE_COUNT] > sb[SEQ_Z_AXIS_MOVE] > sb[SEQ_ACS_PARAMETER_SET] > sb[SEQ_WELDING_MOTION] > sb[SEQ_CHECK_LINE_COUNT]); + + sb.Flows(sb[SEQ_CHECK_LINE_COUNT] > sb[SEQ_MOTION_INTERLOCK] > sb[SEQ_LINE_PROCESS_COMPLETE] > sb.Final); + + //sb.Draw("SplitLineSequence.pdf"); + + return sb; + } + + private static SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param) + { + context.RetryUntilSuccess(() => true, 1000 * 100, 100); + //_data = (ObservableCollection)param.Param; + _manual = (ManualLaserSetting)param.Param; + _data = _manual.Lines; + _LaserIOUse = _manual.LaserIOUse; + + if (_acsMotion is null) + _acsMotion = _acs = context.Devices[CommonDeviceIds.ACS] as ScannerACS; + + //if (_laser is null) + // _laser = context.Devices[CommonDeviceIds.Laser] as Laser; + // _laserCore = _laser.getCore() as LaserTruFiber; + // _laserCal = context.Settings[CommonSettingIds.LaserPowerCalParam] as LaserPowerCalParam; + + //if (_io is null) + // _io = context.Devices[DeviceIds.IODevice] as PrismaticGunACSIO; + + if (_setting is null) + _setting = context.Settings[CommonSettingIds.TeachingPos] as TeachingPositionSetting; + + //if (_stage == eStage.A) + // _AxisX = context.Devices[MotorIds.ALineX] as ACSMotor; + //else + // _AxisX = context.Devices[MotorIds.BLineX] as ACSMotor; + + //if (_stage == eStage.A) + // _AxisY = context.Devices[MotorIds.ALineY] as ACSMotor; + //else + // _AxisY = context.Devices[MotorIds.BLineY] as ACSMotor; + + LineInLinesCount = _data.Count; + LineInLinesIndex = 0; + _laserCal = context.Settings[CommonSettingIds.LaserPowerCalParam] as LaserPowerCalParam; + + _AxisX = context.Devices[CommonMotorIds.AxisX2] as ACSMotor; + _AxisZ = context.Devices[CommonMotorIds.AxisZ] as ACSMotor; + if (_data[LineInLinesIndex].YAxisType == (int)eYAxisType.Y1) { + _AxisY = context.Devices[CommonMotorIds.AxisY1] as ACSMotor; + _acsMotion.SetWeldingAxes((int)CommonMotorIds.eMotorIdx.AxisX2, (int)CommonMotorIds.eMotorIdx.AxisY1); + } + else { + _AxisY = context.Devices[CommonMotorIds.AxisY2] as ACSMotor; + _acsMotion.SetWeldingAxes((int)CommonMotorIds.eMotorIdx.AxisX2, (int)CommonMotorIds.eMotorIdx.AxisY2); + } + + + if (Status.EquipmentStatus == eEqpStatus.Manual) + _spd = AuroraACS.Speed.M; + else + _spd = AuroraACS.Speed.H; + + Thread.Sleep(SLEEP_TIME_MS); + Log.V(">> SeqSplitLIne - Start"); + return SequenceAction.Ok(); + } + + private static SequenceActionResult CheckInitCondition(SequenceContext context, string id, SequenceActionResult param) + { + if (!_AxisX.IsActivated) { + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.DEVICE_STAGE_A_AXISX_DEACTIVATED); //26.04.13 잠시 주석 + return null; + } + + if (!_AxisY.IsActivated) { + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.DEVICE_STAGE_A_AXISY_DEACTIVATED); //26.04.13 잠시 주석 + return null; + } + + if (!((_acsMotion as ScannerACS).IsActivated)) { + Log.E($"[ACS activated({(_acsMotion as ScannerACS).IsActivated})]"); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_DEACTIVATED_DISCONNECTED); // 26.04.13 잠시 주석 + return null; + } + + //if (!(_laser.IsActivated && _laser.GetConnected())) { + // Log.E($"[Laser activated({_laser.IsActivated}) / connected({_laser.GetConnected()})]"); + // context.PutValue("AlarmCode", AlarmCode_PrismaticGun.DEVICE_LASER_DEACTIVATED_DISCONNECTED); + // return null; + //} + + //if (!(_io.IsActivated && _io.IsConnected())) { + // Log.E($"[IO activated({_io.IsActivated}) / connected({_io.IsConnected()})]"); + // context.PutValue("AlarmCode", AlarmCode_PrismaticGun.DEVICE_ACSIO_DEACTIVATED_DISCONNECTED); + // return null; + //} + + return SequenceAction.Ok(); + } + + private static string CheckLineCount(SequenceContext context, string id, ICollection branches, SequenceActionResult param) + { + if (LineInLinesCount > LineInLinesIndex){ + Log.FuncV($">> LineShot Count ({LineInLinesIndex + 1} / {LineInLinesCount})"); + return SEQ_Z_AXIS_MOVE; + } + + Thread.Sleep(SLEEP_TIME_MS); + return SEQ_MOTION_INTERLOCK; + } + private static SequenceActionResult ZAxisMove(SequenceContext context, string id, SequenceActionResult param) + { + _acsMotion.SetLaserIOUse(_LaserIOUse); + var _zPos = _data[LineInLinesIndex].PositionZ; + + if (_AxisZ.IsReachedTargetPosition(_zPos)) + { + Log.V($"Already Z-Axis Process Position"); + return SequenceAction.Ok(); + } + + _AxisZ.SetTargetPos(_zPos, TargetPosType.ABS); + _AxisZ.SetMoveVelocityImm(_spd); + _AxisZ.AccelerationImm(_spd); + _AxisZ.DecelerationImm(_spd); + _AxisZ.JerkImm(_spd); + _AxisZ.Move(); + Log.V($"Move Z Position : {_zPos}"); + + var res = context.RetryUntilSuccess(() => _AxisZ.IsReachedTargetPosition(_zPos), MOTION_TIMEOUT, MOTION_INTERVAL, true); + if (res == E2.TIMEOUT) { + Log.FuncE($"Z-Axis Move Timeout!"); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_Z_MOVE_TIMEOUT); // 26.04.13 잠시 주석 + return null; + } + else if (res == E2.CANCELLED) { + Log.FuncE($"Z-Axis Move Cancel!"); + context.PutValue("AlarmCode", 0); + return null; + } + Log.V($"Move Z Position Complete :{_zPos}"); + + Log.V($"Z Move Complete"); + return SequenceAction.Ok(); + } + + private static SequenceActionResult AcsParameterSetting(SequenceContext context, string id, SequenceActionResult param) + { + var LineData = _data; + LineData[LineInLinesIndex].State = "Working"; + + // 볼트 켈 정도를 가져오기 위해 10을 곱해서 검색한다 + _laserCal.Initialize(_laserCal.PowerCalibrationCenterBeamCSVFile, _laserCal.PowerCalibrationRingBeamCSVFile); + var RealCoreVoltage = (_laserCal.CalibrateWattToMeasuredVoltage(_data[LineInLinesIndex].Core, (uint)LaserPowerCalibrationParam.beamMode.Center)); + var RealRingVoltage = (_laserCal.CalibrateWattToMeasuredVoltage(_data[LineInLinesIndex].Ring, (uint)LaserPowerCalibrationParam.beamMode.Ring)); + + if (double.IsNaN(RealCoreVoltage) || RealCoreVoltage < 0.0) + RealCoreVoltage = 0.0; + if (double.IsNaN(RealRingVoltage) || RealRingVoltage < 0.0) + RealRingVoltage = 0.0; + + var _startX = _data[LineInLinesIndex].StartX; + var _startY = _data[LineInLinesIndex].StartY; + var _endX = _data[LineInLinesIndex].EndX; + var _endY = _data[LineInLinesIndex].EndY; + + if (_data[LineInLinesIndex].YAxisType == (int)eYAxisType.Y1) { + _startX += _manual.CamLaserPositionOffset.Y1UseOffsetX; + _startY -= _manual.CamLaserPositionOffset.Y1UseOffsetY; + _endX += _manual.CamLaserPositionOffset.Y1UseOffsetX; + _endY -= _manual.CamLaserPositionOffset.Y1UseOffsetY; + + } + else { + _startX += _manual.CamLaserPositionOffset.Y2UseOffsetX; + _startY -= _manual.CamLaserPositionOffset.Y2UseOffsetY; + _endX += _manual.CamLaserPositionOffset.Y2UseOffsetX; + _endY -= _manual.CamLaserPositionOffset.Y2UseOffsetY; + } + + var _velocity = _data[LineInLinesIndex].Velocity; + var _acc = _data[LineInLinesIndex].Acc; + + //SetLineShot(double corePower, double ringPower, double startPosX, double endPosX, double startPosY, double endPosY, double velocity, double acc) + _acsMotion.SetLCILserOn(true); + _acsMotion.SetLineShot(RealCoreVoltage, RealRingVoltage, _startX, _endX, _startY, _endY, _velocity, _acc); + _acsMotion.SetLaserIOUse(_LaserIOUse); + + //레이저 출력 셋팅 Jeongin + + Log.V($"ACS Setting Complete"); + return SequenceAction.Ok(); + } + + private static SequenceActionResult WeldingMotion(SequenceContext context, string id, SequenceActionResult param) + { + if (_acsMotion.LineShotStart()) + Log.V($">> {LineInLinesIndex} LineShot Start"); + + Thread.Sleep(500); + var res = context.RetryUntilSuccess(() => _acsMotion.CheckLineShotComp(), SEQ_TIMEOUT, SEQ_CHECK_TIMER); + if (res == E2.TIMEOUT) { + Log.FuncV($">> {LineInLinesIndex} LineShot Fail"); + return null; + } else if(res == E2.CANCELLED) { + Log.FuncV($">> {LineInLinesIndex} LineShot Cancel"); + return null; + } + + _data[LineInLinesIndex].State = "Done"; + + Log.V($"Laser Interlock Start"); + _acsMotion.SetLCILserOn(false); + //ProcessManager.Instance.EnableLaserUse(true); + Log.FuncV($">> {LineInLinesIndex++} : LineShot Complete"); + + Thread.Sleep(SLEEP_TIME_MS); + return SequenceAction.Ok(); + } + + private static SequenceActionResult MotionInterlock(SequenceContext context, string id, SequenceActionResult param) + { + if (Status.EquipmentStatus == eEqpStatus.Manual) { + //_laserCore.LaserOff(); + Log.I("Manual Laser Off"); + } + + return SequenceAction.Ok(); + } + + + private static SequenceActionResult LineProcessComplete(SequenceContext context, string id, SequenceActionResult param) + { + LineInLinesIndex = 0; + //ProcessManager.Instance.EnableLaserUse(true); + //_laser.LaserOff(); + _acsMotion.SetLCILserOn(false); + Log.FuncV(">> All LineShot Complete"); + MessageUtil.ShowSuccessToast(">> All LineShot Complete"); + return SequenceAction.Ok(); + } + + private static void OnStopped(SequenceContext context) + { + LineInLinesIndex = 0; + //ProcessManager.Instance.EnableLaserUse(true); + //_laser.LaserOff(); + _acsMotion.SetLCILserOn(false); + + Log.FuncV(">> All LineShot Fail"); + MessageUtil.ShowWarningToast(">> Sequence Stop"); + return; + } + + private static void OnForceError(SequenceContext context, string arg2) + { + LineInLinesIndex = 0; + //ProcessManager.Instance.EnableLaserUse(true); + //_laser.LaserOff(); + _acsMotion.SetLCILserOn(false); + + Log.FuncV(">> All LineShot Fail"); + MessageUtil.ShowErrorToast(">> Sequence Fail"); + return; + } + } +} diff --git a/WeldingComponents/WeldingCommon/Sequences/Gun/SubSequence/StageA/SeqTeachingPosMoveStageA.cs b/WeldingComponents/WeldingCommon/Sequences/Gun/SubSequence/StageA/SeqTeachingPosMoveStageA.cs new file mode 100644 index 0000000..df360d3 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Sequences/Gun/SubSequence/StageA/SeqTeachingPosMoveStageA.cs @@ -0,0 +1,325 @@ +using Aurora.Api; +using Aurora.Api.Devices; +using AuroraACS; +using AuroraMotionBoard.Ajin; +using Hermes; +using WeldingCommon.Alarm; +using WeldingCommon.Device; +using WeldingCommon.Device.ACS; +using WeldingCommon.Process; +using WeldingCommon.Settings; +using System; +using System.Collections.Generic; +using System.Windows; +using WeldingCommon; +using WeldingCommon.Sequences; +using WeldingCommon.Devices.ACS; + +namespace WeldingCommon.Sequences.SubSequence.StageA +{ + public class SeqTeachingPosMoveStageA + { + static readonly Logger Log = new Logger("SeqTeachingPosMoveStageA", "StageA"); + + const int MOTION_TIMEOUT = 30 * 1000; // sec, Timeout은 시퀀스 정지가 아니라 타임아웃 시간마다 로그만 남기도록 한다 + const int MOTION_INTERVAL = 20; + + const int PLC_TIMEOUT = 10 * 1000; // sec, Timeout은 시퀀스 정지가 아니라 타임아웃 시간마다 로그만 남기도록 한다 + const int NODE_SLEEP = 100; + + const string SEQ_ENTER = "SEQ_ENTER"; + const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; + const string SEQ_MOVE_AXIS_Z_SAFETY_POS = "Move Axis Z SafetyPos"; + const string SEQ_MOVE_XYSTAGE_AXIS = "Move XY Stage Axis"; + const string SEQ_MOVE_ZAXIS = "Move Z Axis"; + const string SEQ_COMPLETE = "SEQ_COMPLETE"; // 정상 종료 + + private static eTeachingPosition _targetPos; + private static TeachingPositionSetting _setting; + + private static ScannerACS _acs; // 26.04.13 + private static ACSMotor _AxisX; + private static ACSMotor _AxisY1; + private static ACSMotor _AxisY2; + private static ACSMotor _AxisZ; + + private static ACSMotor _FirstMoveAxis; + private static ACSMotor _SecondMoveAxis; + + static private AuroraACS.Speed _speed = AuroraACS.Speed.H; + + public static SequenceBuilder Builder() + { + var sb = new SequenceBuilder(1000, true); + // out Activation On >> wait Laser Ready >> out Pstart On >> wait ProgActive + + sb.AddAction(SEQ_ENTER, Sequence_Enter); + sb.AddDecision(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); + sb.AddAction(SEQ_MOVE_AXIS_Z_SAFETY_POS, MoveAxisZSafetyPos); + sb.AddAction(SEQ_MOVE_XYSTAGE_AXIS, MoveXYStage); + sb.AddAction(SEQ_MOVE_ZAXIS, MoveZAxis); + sb.AddAction(SEQ_COMPLETE, Complete); + + sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION]); + sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_MOVE_AXIS_Z_SAFETY_POS] > sb[SEQ_MOVE_XYSTAGE_AXIS] > sb[SEQ_MOVE_ZAXIS] > sb[SEQ_COMPLETE] > sb.Final); + sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_COMPLETE] > sb.Final); + + sb.OnStopped(OnStopped); + sb.OnForceError(OnForceError); + + //sb.Draw("SeqTeachingPosMoveStageA.pdf"); + + return sb; + } + + private static SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param) + { + _targetPos = (eTeachingPosition)param.Param; + + if (_acs is null) + _acs = context.Devices[CommonDeviceIds.ACS] as ScannerACS; //260413 + if (_AxisX is null) + _AxisX = _FirstMoveAxis = context.Devices[CommonDeviceIds.AxisX2] as ACSMotor; + if (_AxisY1 is null) + _AxisY1 = _SecondMoveAxis = context.Devices[CommonDeviceIds.AxisY1] as ACSMotor; + if (_AxisY2 is null) + _AxisY2 = _SecondMoveAxis = context.Devices[CommonDeviceIds.AxisY2] as ACSMotor; + if (_AxisZ is null) + _AxisZ = context.Devices[CommonDeviceIds.AxisZ] as ACSMotor; + + if (_setting is null) + _setting = context.Settings[CommonDeviceIds.TeachingPos] as TeachingPositionSetting; + + if (Status.EquipmentStatus == eEqpStatus.Manual) + _speed = AuroraACS.Speed.M; + else + _speed = AuroraACS.Speed.H; + + return SequenceAction.Ok(); + } + private static string CheckInitCondition(SequenceContext context, string id, ICollection branches, SequenceActionResult param) + { + Log.I($"Teaching Position[{Enum.GetName(typeof(eTeachingPosition), _targetPos)}] Move Start"); + + if (_acs.IsReachedTeachingPosition(_targetPos)){ + Log.V($"Already teaching Position"); + return SEQ_COMPLETE; + } + + var target = _setting.Get(_targetPos); + if (target.AxisX < -998 || target.AxisY1 < -998 || target.AxisY2 < -998 || target.AxisZ < -998) { + Log.FuncE("이동 할 Teachig Position의 값 중 -999가 있습니다."); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_TEACHING_POSITION); //26.04.13 잠시 주석 + return null; + } + + return SEQ_MOVE_AXIS_Z_SAFETY_POS; + } + + private static SequenceActionResult MoveAxisZSafetyPos(SequenceContext context, string id, SequenceActionResult param) + { + var safety = _setting.Get(eTeachingPosition.SafetyPosition); + if (_AxisZ.IsReachedTargetPosition(safety.AxisZ)){ + Log.V($"Already Z-Axis(SafetyPosition) Position"); + return SequenceAction.Ok(); + } + + _AxisZ.SetTargetPos(safety.AxisZ, TargetPosType.ABS); + _AxisZ.SetMoveVelocityImm(_speed); + _AxisZ.AccelerationImm(_speed); + _AxisZ.DecelerationImm(_speed); + _AxisZ.JerkImm(_speed); + _AxisZ.Move(); + Log.V($"Move Z Position : {safety.AxisZ}"); + + var res = context.RetryUntilSuccess(() => _AxisZ.IsReachedTargetPosition(safety.AxisZ), MOTION_TIMEOUT, MOTION_INTERVAL, true); + if (res == E2.TIMEOUT) { + Log.FuncE($"Z-Axis({Enum.GetName(typeof(eTeachingPosition), eTeachingPosition.SafetyPosition)}) Move Timeout!"); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_Z_MOVE_TIMEOUT); // 26.04.13 잠시 주석 + return null; + } else if (res == E2.CANCELLED) { + Log.FuncE($"Z-Axis({Enum.GetName(typeof(eTeachingPosition), eTeachingPosition.SafetyPosition)}) Move Cancel!"); + context.PutValue("AlarmCode", 0); + return null; + } + Log.V($"Move Z Position Complete :{safety.AxisZ}"); + + return SequenceAction.Ok(); + } + + private static SequenceActionResult MoveXYStage(SequenceContext context, string id, SequenceActionResult param) + { + var target = _setting.Get(_targetPos); + if (_AxisX.IsReachedTargetPosition(target.AxisX) + && _AxisY1.IsReachedTargetPosition(target.AxisY1) + && _AxisY2.IsReachedTargetPosition(target.AxisY2)) { + Log.V($"Already teaching Position"); + return SequenceAction.Ok(); + } + _AxisX.SetTargetPos(target.AxisX, TargetPosType.ABS); + _AxisX.SetMoveVelocityImm(_speed); + _AxisX.AccelerationImm(_speed); + _AxisX.DecelerationImm(_speed); + _AxisX.JerkImm(_speed); + _AxisX.Move(); + Log.V($"Move X Position : {target.AxisX}"); + + _AxisY1.SetTargetPos(target.AxisY1, TargetPosType.ABS); + _AxisY1.SetMoveVelocityImm(_speed); + _AxisY1.AccelerationImm(_speed); + _AxisY1.DecelerationImm(_speed); + _AxisY1.JerkImm(_speed); + _AxisY1.Move(); + Log.V($"Move Y1 Position : {target.AxisY1}"); + + _AxisY2.SetTargetPos(target.AxisY2, TargetPosType.ABS); + _AxisY2.SetMoveVelocityImm(_speed); + _AxisY2.AccelerationImm(_speed); + _AxisY2.DecelerationImm(_speed); + _AxisY2.JerkImm(_speed); + _AxisY2.Move(); + Log.V($"Move Y2 Position : {target.AxisY2}"); + + var res = context.RetryUntilSuccess(() => _AxisX.IsReachedTargetPosition(target.AxisX) + && _AxisY1.IsReachedTargetPosition(target.AxisY1) && _AxisY2.IsReachedTargetPosition(target.AxisY2), MOTION_TIMEOUT, MOTION_INTERVAL, true); + if (res == E2.TIMEOUT) + { + Log.FuncE($"XY Stage {Enum.GetName(typeof(eTeachingPosition), _targetPos)} Move Timeout!"); + return null; + } + else if (res == E2.CANCELLED) + { + Log.FuncE($"XY Stage {Enum.GetName(typeof(eTeachingPosition), _targetPos)} Move Cancel!"); + return null; + } + Log.V($"Move XY Position Complete :{target.AxisX}"); + Log.V($"Move Y2 Position Complete :{target.AxisY1}"); + Log.V($"Move Y1 Position Complete :{target.AxisY2}"); + + return SequenceAction.Ok(); + } + + private static SequenceActionResult MoveZAxis(SequenceContext context, string id, SequenceActionResult param) + { + var target = _setting.Get(_targetPos); + + _AxisZ.SetTargetPos(target.AxisZ, TargetPosType.ABS); + _AxisZ.SetMoveVelocityImm(_speed); + _AxisZ.AccelerationImm(_speed); + _AxisZ.DecelerationImm(_speed); + _AxisZ.JerkImm(_speed); + _AxisZ.Move(); + Log.V($"Move Z Position : {target.AxisZ}"); + + var res = context.RetryUntilSuccess(() => _AxisZ.IsReachedTargetPosition(target.AxisZ), MOTION_TIMEOUT, MOTION_INTERVAL, true); + if (res == E2.TIMEOUT) + { + Log.FuncE($"Z-Axis({Enum.GetName(typeof(eTeachingPosition), _targetPos)}) Move Timeout!"); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_Z_MOVE_TIMEOUT); // 26.04.13 잠시 주석 + return null; + } + else if (res == E2.CANCELLED) + { + Log.FuncE($"Z-Axis({Enum.GetName(typeof(eTeachingPosition), _targetPos)}) Move Cancel!"); + context.PutValue("AlarmCode", 0); + return null; + } + Log.V($"Move Z Position Complete :{target.AxisZ}"); + + return SequenceAction.Ok(); + } + + //private static SequenceActionResult MoveFirstAxis(SequenceContext context, string id, SequenceActionResult param) + //{ + // var target = _setting.Get(eStage.A, _targetPos); + // var First_Is_AxisX = _FirstMoveAxis.DeviceId.Contains(MotorIds.AxisX); + // var TargetPos = First_Is_AxisX ? target.AxisX : target.AxisY; + // if (_FirstMoveAxis.IsReachedTargetPosition(TargetPos)) { + // return SequenceAction.Ok(); + // } + + // _FirstMoveAxis.SetTargetPos(TargetPos, TargetPosType.ABS); + // _FirstMoveAxis.SetMoveVelocityImm(_speed); + // _FirstMoveAxis.AccelerationImm(_speed); + // _FirstMoveAxis.DecelerationImm(_speed); + // _FirstMoveAxis.JerkImm(_speed); + // _FirstMoveAxis.Move(); + // Log.V($"Move FirstAxis({_FirstMoveAxis.DeviceId}) Position : {TargetPos}"); + + // var res = context.RetryUntilSuccess(() => _FirstMoveAxis.IsReachedTargetPosition(TargetPos), MOTION_TIMEOUT, MOTION_INTERVAL, true); + // if (res == E2.TIMEOUT) { + // Log.FuncE($"{_FirstMoveAxis.DeviceId} ({Enum.GetName(typeof(eTeachingPosition), _targetPos)}) Move Timeout!"); + // context.PutValue("AlarmCode", First_Is_AxisX ? AlarmCode_PrismaticGun.STAGE_A_X_MOVE_TIMEOUT : AlarmCode_PrismaticGun.STAGE_A_Y_MOVE_TIMEOUT); + // return null; + // } else if (res == E2.CANCELLED) { + // Log.FuncE($"{_FirstMoveAxis.DeviceId} ({Enum.GetName(typeof(eTeachingPosition), _targetPos)}) Move Cancel!"); + // context.PutValue("AlarmCode", 0); + // return null; + // } + // var Position = First_Is_AxisX ? _acs.MotionVariables[eStage.A].XAxisPosition : _acs.MotionVariables[eStage.A].Y1AxisPosition; + // Log.V($"Move FirstAxis({_FirstMoveAxis.DeviceId}) Position Complete : {Position}"); + // return SequenceAction.Ok(); + //} + + //private static SequenceActionResult MoveSecondAxis(SequenceContext context, string id, SequenceActionResult param) + //{ + // var target = _setting.Get(eStage.A, _targetPos); + // var Second_Is_AxisX = _SecondMoveAxis.DeviceId.Contains(MotorIds.AxisX); + // var TargetPos = Second_Is_AxisX ? target.AxisX : target.AxisY; + // if (_SecondMoveAxis.IsReachedTargetPosition(TargetPos)) { + // return SequenceAction.Ok(); + // } + + // _SecondMoveAxis.SetTargetPos(TargetPos, TargetPosType.ABS); + // _SecondMoveAxis.SetMoveVelocityImm(_speed); + // _SecondMoveAxis.AccelerationImm(_speed); + // _SecondMoveAxis.DecelerationImm(_speed); + // _SecondMoveAxis.JerkImm(_speed); + // _SecondMoveAxis.Move(); + // Log.V($"Move Second({_SecondMoveAxis.DeviceId}) Position : {TargetPos}"); + + // var res = context.RetryUntilSuccess(() => _SecondMoveAxis.IsReachedTargetPosition(TargetPos), MOTION_TIMEOUT, MOTION_INTERVAL, true); + // if (res == E2.TIMEOUT) { + // Log.FuncE($"{_SecondMoveAxis.DeviceId} ({Enum.GetName(typeof(eTeachingPosition), _targetPos)}) Move Timeout!"); + // context.PutValue("AlarmCode", Second_Is_AxisX ? AlarmCode_PrismaticGun.STAGE_A_X_MOVE_TIMEOUT : AlarmCode_PrismaticGun.STAGE_A_Y_MOVE_TIMEOUT); + // return null; + // } else if (res == E2.CANCELLED) { + // Log.FuncE($"{_SecondMoveAxis.DeviceId} ({Enum.GetName(typeof(eTeachingPosition), _targetPos)}) Move Cancel!"); + // context.PutValue("AlarmCode", 0); + // return null; + // } + // var Position = Second_Is_AxisX ? _acs.MotionVariables[eStage.A].XAxisPosition : _acs.MotionVariables[eStage.A].Y1AxisPosition; + // Log.V($"Move FirstAxis({_SecondMoveAxis.DeviceId}) Position Complete : {Position}"); + // return SequenceAction.Ok(); + //} + + private static SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param) + { + + if (Status.EquipmentStatus == eEqpStatus.Manual) + MessageBox.Show($"{Enum.GetName(typeof(eTeachingPosition), _targetPos)} 위치 이동 완료"); + else + _speed = AuroraACS.Speed.H; + + return SequenceAction.Ok(); + } + + private static void OnStopped(SequenceContext context) + { + _FirstMoveAxis.Stop(); + _SecondMoveAxis.Stop(); + _AxisZ.Stop(); + } + + private static void OnForceError(SequenceContext context, string arg2) + { + var AlarmCode = context.GetValue("AlarmCode"); + if(AlarmCode > 0) + Log.E(context.AlarmAccured(AlarmCode)); + + _FirstMoveAxis.Stop(); + _SecondMoveAxis.Stop(); + _AxisZ.Stop(); + } + } +} diff --git a/WeldingComponents/WeldingCommon/Sequences/Gun/SubSequence/StageA/SeqWeldingCellStageA.cs b/WeldingComponents/WeldingCommon/Sequences/Gun/SubSequence/StageA/SeqWeldingCellStageA.cs new file mode 100644 index 0000000..317de22 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Sequences/Gun/SubSequence/StageA/SeqWeldingCellStageA.cs @@ -0,0 +1,459 @@ +using Aurora.Api.Devices; +using Aurora.Api; +using AuroraACS; +using AuroraLaser.Trumpf; +using AuroraLaser; +using AuroraMassFlowMeter; +using AuroraMotionBoard.Ajin; +using Hermes; +using WeldingCommon.Device.ACS; +using WeldingCommon.Device; +using WeldingCommon.Process; +using WeldingCommon.Recipes; +using WeldingCommon.Settings; +using System.Threading; +using static AuroraOCT.Trumpf.OCT; +using WeldingCommon; +using WeldingCommon.Alarm; +using WeldingCommon.Sequences; +//using WeldingCommon.Alarm; // Gun Alarm도 넣어야 함 +using System.Diagnostics; +using System; +using System.Collections.Generic; +//using AuroraHeightSensor; // 26.04.13 잠시 주석 +using WeldingCommon.Tools; +using AuroraOCT.Trumpf; +using WeldingCommon.Data; +using WeldingCommon.Settings; +using Aurora; +using WeldingCommon.Devices.ACS; + +namespace WeldingCommon.Sequences.SubSequence.StageA +{ + public class SeqWeldingCellStageA + { + static readonly Logger Log = new Logger("SeqWeldingCellStageA", "StageA"); + + const string SEQ_ENTER = "SEQ_ENTER"; + const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; + const string SEQ_SET_ACS_WELDING_PARAM = "Set ACS Process Parameter"; // ACS Process Param Setting + const string SEQ_ZAXIS_POSITION_MOVE = "Z Axis Welding Position Move"; + const string SEQ_CHECK_PROCESS_MODE = "Check Process Mode"; + const string SEQ_REQUEST_LASER_USE_WAIT = "Request Laser Use & Wait"; // Laser Interface >> 비트 살려야 할것으로 보임 + const string SEQ_ACS_WELDING_START = "ACS Process Start"; // ACS Motion + const string SEQ_ACS_WELDING_COMPLETE = "Wait for ACS Process Complete"; + const string SEQ_CHECK_INTERLOCK = "Check Interlock"; + const string SEQ_COMPLETE = "SEQ_COMPLETE"; // 정상 종료 + + const int MOTION_TIMEOUT = 10 * 1000; + const int WELDING_TIMEOUT = 100 * 1000; + const int MOTION_INTERVAL = 20; + + const int IO_TIMEOUT = 60 * 1000; + const int WELDING_WAIT = 2 * 60 * 60 * 1000; // 시분초 + const int NODE_SLEEP = 100; + + private static ScannerACS _acs; + private static IScannerACS _motion; + private static Laser _laser; + private static LaserPowerCalParam _laserCal; + private static LaserTruFiber _laserCore; + + private static PalletInfo _targetCell; + private static MainRecipe _mainRecipe; + + private static ACSMotor _AxisX; + private static ACSMotor _AxisY; + private static ACSMotor _AxisZ; + private static ACSMotor _MotorY1, _MotorY2; + + private static TeachingPositionSetting _setting; + private static ManualLaserSetting _manual; + + static private AuroraACS.Speed _speed = AuroraACS.Speed.H; + + private static bool _LaserUse = false; + + public static SequenceBuilder Builder() + { + var sb = new SequenceBuilder(1000, true); + + sb.AddAction(SEQ_ENTER, Sequence_Enter); + sb.AddAction(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); + sb.AddAction(SEQ_SET_ACS_WELDING_PARAM, SetACSProcessParam); //ACS Parameter setting (용접위치, 아날로그 출력 관련) + sb.AddAction(SEQ_ZAXIS_POSITION_MOVE, ZAxisWeldingPosMove); //Z축 이동 완료 확인 + sb.AddDecision(SEQ_CHECK_PROCESS_MODE, CheckProcessMode); //Review(미출사) Mode 확인 + sb.AddAction(SEQ_REQUEST_LASER_USE_WAIT, RequestLaserUseWait); //레이저 통신 및 I/O setting + sb.AddAction(SEQ_ACS_WELDING_START, StartACSWelding); + sb.AddAction(SEQ_ACS_WELDING_COMPLETE, WaitACSWeldingComp); + sb.AddAction(SEQ_CHECK_INTERLOCK, CheckInterlock); + sb.AddAction(SEQ_COMPLETE, Complete); + + sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION]); + sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_SET_ACS_WELDING_PARAM] > sb[SEQ_ZAXIS_POSITION_MOVE] > sb[SEQ_CHECK_PROCESS_MODE] > sb[SEQ_REQUEST_LASER_USE_WAIT] + > sb[SEQ_ACS_WELDING_START] > sb[SEQ_ACS_WELDING_COMPLETE] > sb[SEQ_CHECK_INTERLOCK] > sb[SEQ_COMPLETE] > sb.Final); + + sb.OnStopped(OnStopped); + sb.OnForceError(OnForceError); + + //sb.Draw("SeqWeldingCellStageA.pdf"); + + return sb; + } + + private static SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param) + { + //if (param.Param is PalletInfo info) + // _targetCell = info; + + //if (Status.EquipmentStatus is eEqpStatus.Auto) + // _targetCell = ProcessManager.Instance.PalletInStageA; + + if (_motion is null) + _motion = _acs = context.Devices[CommonDeviceIds.ACS] as ScannerACS; + + //if (_laser is null) + // _laser = context.Devices[CommonDeviceIds.Laser] as Laser; + //_laserCore = _laser.getCore() as LaserTruFiber; + _laserCal = context.Settings[CommonSettingIds.LaserPowerCalParam] as LaserPowerCalParam; + + _mainRecipe = context.Recipes.ActivatedRecipeItem(CommonRecipeIds.StageAMainRecipe) as MainRecipe; + + if (_manual is null) + _manual = context.Settings[CommonSettingIds.ManualLaser] as ManualLaserSetting; + + _AxisX = context.Devices[CommonMotorIds.AxisX2] as ACSMotor; + _AxisZ = context.Devices[CommonMotorIds.AxisZ] as ACSMotor; + _MotorY1 = context.Devices[CommonMotorIds.AxisY1] as ACSMotor; + _MotorY2 = context.Devices[CommonMotorIds.AxisY2] as ACSMotor; + + if (_mainRecipe.YAxisUseType == MainRecipe.YAxisType.Y1) { + _AxisY = _MotorY1; + _motion.SetWeldingAxes((int)CommonMotorIds.eMotorIdx.AxisX2, (int)CommonMotorIds.eMotorIdx.AxisY1); + } + else { + _AxisY = _MotorY2; + _motion.SetWeldingAxes((int)CommonMotorIds.eMotorIdx.AxisX2, (int)CommonMotorIds.eMotorIdx.AxisY2); + } + + if (_setting is null) + _setting = context.Settings[CommonSettingIds.TeachingPos] as TeachingPositionSetting; + + if (Status.EquipmentStatus == eEqpStatus.Manual) + _speed = AuroraACS.Speed.M; + else + _speed = AuroraACS.Speed.H; + + _LaserUse = true; + return SequenceAction.Ok(); + } + + private static SequenceActionResult CheckInitCondition(SequenceContext context, string id, SequenceActionResult param) + { + if (AlarmManager.HasAlarmLevelHigh()) { + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.HAS_HEAVY_ALARM); //26.04.13 잠시 주석 + return null; + } + + if (!((_motion as ScannerACS).IsActivated)) { + Log.E($"[ACS activated({(_motion as ScannerACS).IsActivated})]"); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_DEACTIVATED_DISCONNECTED); //26.04.13 잠시 주석 + return null; + } + //if (!(_laser.IsActivated && _laser.GetConnected())) { + // Log.E($"[Laser activated({_laser.IsActivated}) / connected({_laser.GetConnected()})]"); + // context.PutValue("AlarmCode", AlarmCode_PrismaticGun.DEVICE_LASER_DEACTIVATED_DISCONNECTED); + // return null; + //} + + return SequenceAction.Ok(_targetCell); + } + + private static SequenceActionResult SetACSProcessParam(SequenceContext context, string id, SequenceActionResult param) + { + Log.V($"Set Laser Params(PC->ACS) Start"); + + // 볼트 켈 정도를 가져오기 위해 10을 곱해서 검색한다 + _laserCal.Initialize(_laserCal.PowerCalibrationCenterBeamCSVFile, _laserCal.PowerCalibrationRingBeamCSVFile); + var RealCoreStraightVoltage = (_laserCal.CalibrateWattToMeasuredVoltage((_mainRecipe.StraightParam.CorePowerW), (uint)LaserPowerCalibrationParam.beamMode.Center)); + var RealCoreCornerVoltage = (_laserCal.CalibrateWattToMeasuredVoltage((_mainRecipe.CurveParam.CorePowerW), (uint)LaserPowerCalibrationParam.beamMode.Center)); + + var RealRingStraightVoltage = (_laserCal.CalibrateWattToMeasuredVoltage((_mainRecipe.StraightParam.RingPowerW), (uint)LaserPowerCalibrationParam.beamMode.Ring)); + var RealRingCornerVoltage = (_laserCal.CalibrateWattToMeasuredVoltage((_mainRecipe.CurveParam.RingPowerW), (uint)LaserPowerCalibrationParam.beamMode.Ring)); + + if (double.IsNaN(RealCoreStraightVoltage) || RealCoreStraightVoltage < 0.0) + RealCoreStraightVoltage = 0.0; + if (double.IsNaN(RealCoreCornerVoltage) || RealCoreCornerVoltage < 0.0) + RealCoreCornerVoltage = 0.0; + + if (double.IsNaN(RealRingStraightVoltage) || RealRingStraightVoltage < 0.0) + RealRingStraightVoltage = 0.0; + if (double.IsNaN(RealRingCornerVoltage) || RealRingCornerVoltage < 0.0) + RealRingCornerVoltage = 0.0; + + _motion.SetWeldingPulse(RealCoreStraightVoltage, RealCoreCornerVoltage, RealRingStraightVoltage, RealRingCornerVoltage); + Log.I($"Straight Laser Core Power Watt({_mainRecipe.StraightParam.CorePowerW}) / Votage({RealCoreStraightVoltage})"); + Log.I($"Corner Laser Core Power Watt({_mainRecipe.CurveParam.CorePowerW}) / Votage({RealCoreCornerVoltage})"); + Log.I($"Straight Laser Ring Power Watt({_mainRecipe.StraightParam.RingPowerW}) / Votage({RealRingStraightVoltage})"); + Log.I($"Corner Laser Ring Power Watt({_mainRecipe.CurveParam.RingPowerW}) / Votage({RealRingCornerVoltage})"); + + double camOffsetX = 0.0; + double camOffsetY = 0.0; + + if (_mainRecipe.YAxisUseType == MainRecipe.YAxisType.Y1) { + camOffsetX = (-1) * _manual.CamLaserPositionOffset.Y1UseOffsetX; + camOffsetY = (-1) * _manual.CamLaserPositionOffset.Y1UseOffsetY; + } + else { + camOffsetX = (-1) * _manual.CamLaserPositionOffset.Y2UseOffsetX; + camOffsetY = (-1) * _manual.CamLaserPositionOffset.Y2UseOffsetY; + } + + _motion.SetWeldingPos(_mainRecipe.StartPos.PosX, _mainRecipe.StartPos.PosY, _mainRecipe.EndPos.PosX, _mainRecipe.EndPos.PosY, camOffsetX, camOffsetY);// + _motion.SetWeldingVel(_mainRecipe.WeldingAcc, _mainRecipe.StraightParam.Velocity, _mainRecipe.CurveParam.Velocity); + _motion.SetWeldingArc(_mainRecipe.Arc1.Size, _mainRecipe.Arc2.Size, _mainRecipe.Arc3.Size, _mainRecipe.Arc4.Size); + + _motion.SetLaserOnOff(_mainRecipe.LaserOnPosition, 0.0, 0.0, 0.0, camOffsetX, camOffsetY);// + _motion.SetRamppingOffParameter(_mainRecipe.RampingOffStartPos, _mainRecipe.RampingOffOverlapDist, _mainRecipe.RampingOffEndPower, camOffsetX, camOffsetY);// + _motion.SetRamppingOnParameter(_mainRecipe.RampingOnOverlapDist, _mainRecipe.RampingOnStartPower);// + + _motion.SetWeldingTeachingPosition2(_mainRecipe.Units[1].PosX, _mainRecipe.Units[1].PosY, camOffsetX, camOffsetY); + _motion.SetWeldingTeachingPosition3(_mainRecipe.Units[2].PosX, _mainRecipe.Units[2].PosY, camOffsetX, camOffsetY); + _motion.SetWeldingTeachingPosition4(_mainRecipe.Units[3].PosX, _mainRecipe.Units[3].PosY, camOffsetX, camOffsetY); + _motion.SetWeldingTeachingPosition1(_mainRecipe.Units[0].PosX, _mainRecipe.Units[0].PosY, camOffsetX, camOffsetY); + _motion.SetWeldingTeachingPosition5(_mainRecipe.Units[4].PosX, _mainRecipe.Units[4].PosY, camOffsetX, camOffsetY); + _motion.SetWeldingTeachingPosition6(_mainRecipe.Units[5].PosX, _mainRecipe.Units[5].PosY, camOffsetX, camOffsetY); + _motion.SetWeldingTeachingPosition7(_mainRecipe.Units[6].PosX, _mainRecipe.Units[6].PosY, camOffsetX, camOffsetY); + _motion.SetWeldingTeachingPosition8(_mainRecipe.Units[7].PosX, _mainRecipe.Units[7].PosY, camOffsetX, camOffsetY); + Log.V($"Set Laser Params(PC->ACS) Complete"); + + return SequenceAction.Ok(); + } + + private static SequenceActionResult ZAxisWeldingPosMove(SequenceContext context, string id, SequenceActionResult param) + { + // 시작 전 미사용 Y 위치이동 + if (_mainRecipe.YAxisUseType == MainRecipe.YAxisType.Y1) + { + _MotorY2.SetTargetPos(_setting.SettingPositions[(int)eTeachingPosition.StageWeldingStartPos].AxisY2, TargetPosType.ABS); + _MotorY2.SetMoveVelocityImm(_speed); + _MotorY2.Move(); + Log.V($"Move Y2 Position : {_setting.SettingPositions[(int)eTeachingPosition.StageWeldingStartPos].AxisY2}"); + } + else + { + _MotorY1.SetTargetPos(_setting.SettingPositions[(int)eTeachingPosition.StageWeldingStartPos].AxisY1, TargetPosType.ABS); + _MotorY1.SetMoveVelocityImm(_speed); + _MotorY1.Move(); + Log.V($"Move Y1 Position : {_setting.SettingPositions[(int)eTeachingPosition.StageWeldingStartPos].AxisY1}"); + } + + _AxisZ.SetTargetPos(_mainRecipe.AxisZPosition, TargetPosType.ABS); + _AxisZ.SetMoveVelocityImm(_speed); + _AxisZ.AccelerationImm(_speed); + _AxisZ.DecelerationImm(_speed); + _AxisZ.JerkImm(_speed); + _AxisZ.Move(); + Log.V($"Move Z Position : {_mainRecipe.AxisZPosition}"); + + var _res = context.RetryUntilSuccess(() => _AxisZ.IsReachedTargetPosition(_mainRecipe.AxisZPosition), MOTION_TIMEOUT, MOTION_INTERVAL, true); + if (_res == E2.TIMEOUT) { + Log.FuncE($"Z-Axis({_mainRecipe.AxisZPosition}) Move Timeout!"); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_Z_MOVE_TIMEOUT); // 26.04.13 잠시 주석 + return null; + } else if (_res == E2.CANCELLED) { + Log.FuncE($"Z-Axis({_mainRecipe.AxisZPosition}) Move Cancel!"); + context.PutValue("AlarmCode", 0); + return null; + } + Log.V($"Check Axis Z Position({_mainRecipe.AxisZPosition}) Complete"); + return SequenceAction.Ok(); + } + + private static string CheckProcessMode(SequenceContext context, string id, ICollection branches, SequenceActionResult param) + { + //Log.W($"{_targetCell.ToString()} TACT LOAD MOVE TO WELD START >> {(DateTime.Now - _targetCell.weldingData.LoadStartTime).TotalSeconds}"); + + //var IsDryRun = _plc.ReadBit(PLCControllerPrismaticGun.eBitInput.DRY_RUN).data; + //var IsStageBOnlyUse = _plc.ReadBit(PLCControllerPrismaticGun.eBitInput.PLC_STAGE_B_ONLY_USE).data; + //var IsAuto = Status.EquipmentStatus == eEqpStatus.Auto; + //_ByPass = !IsDryRun; + //_ByPass &= !_targetCell.weldingData.IsCellExist; // Dry Run이 아니면서 Cell 정보를 안주면 Bypass >> 근데 NG가 나면 무조건 ByPass + + //_ByPass |= _targetCell.weldingData.NgJudge > 0; + //_ByPass |= _targetCell.weldingData.IsAlreadyWelding; + //_ByPass |= IsStageBOnlyUse && IsAuto; + + //if (_ByPass) { + // Log.V($"{_targetCell.ToString()}ByPass({_ByPass}) >> DryRun({IsDryRun}) >> IsAlreadyWelding({_targetCell.weldingData.IsAlreadyWelding}) >> B Only Use({IsStageBOnlyUse})"); + // _targetCell.weldingData.WeldingStartTime = DateTime.Now; + // ProcessManager.Instance.WeldingComplete(_targetCell); + // return SEQ_MOTION_INTERLOCK; + //} + + //Log.I($"{_targetCell.ToString()} Check Cell Exist Real"); + //_heightSensor.MeasureAll(out List val); + //if (val == null || val.Count < 4) { + // Log.FuncE("Height Sensor Measure Fail!"); + // context.PutValue("AlarmCode", AlarmCode_PrismaticGun.STAGE_A_HEIGHT_MEASURE_ERROR); + // return null; + //} + + //// Cell 데이터가 있는데 실물은 없으면서 DryRun이 아니면서 + //var RealCellExist = _setting.RealCellExistRangeMinStageA < val[(int)_targetCell.WeldingStage * 2] && val[(int)_targetCell.WeldingStage * 2] < _setting.RealCellExistRangeMaxStageA; + //var InvalidCellExist = _targetCell.weldingData.IsCellExist != RealCellExist; + //Log.I($"Cell Exist Range Neg({_setting.RealCellExistRangeMinStageA}) < CurrentCellHeight({val[(int)_targetCell.WeldingStage * 2]}) < Cell Exist Range Pos({_setting.RealCellExistRangeMaxStageA})"); + + //// Cell 데이터가 있는데 실물은 없으면서 DryRun이 아니면서 + //if (InvalidCellExist && !_mainRecipe.IsReviewMode && !IsDryRun) { + // Log.FuncE("실물 정보와 PLC에서 받은 데이터가 일치하지 않습니다. 계속하시려면 리뷰모드를 켜고 진행하시기 바랍니다."); + // context.PutValue("AlarmCode", AlarmCode_PrismaticGun.INVALID_CELL_INFOMATION); + // return null; + //} + + //_LaserUse = !IsDryRun; + //_LaserUse &= _targetCell.weldingData.IsCellExist; + _LaserUse &= !_mainRecipe.IsReviewMode; + + _motion.SetLaserIOUse(_LaserUse); + _motion.SetLCILserOn(true); + Log.V($"LaserUse({_LaserUse}) >> ReviewMode({_mainRecipe.IsReviewMode})"); + return SEQ_REQUEST_LASER_USE_WAIT; + } + + /// + /// OutputIO.TRUMPF_LASER_EXT_ACTIVATION_LASER_ON_REQUEST_LASER >> On + /// InputIO.TRUMPF_LASER_READY >> On + /// OutputIO.TRUMPF_LASER_PROGRAM_No >> On + /// OutputIO.TRUMPF_LASER_PSTART_STATICAL >> On + /// InputIO.TRUMPF_LASER_READY >> Off + /// InputIO.TRUMPF_LASER_PROG_ACTIVE >> On + /// ---------running + /// Output.TRUMPF_LASER_PSTART_STATICAL >> Off + /// Input.TRUMPF_LASER_PROG_COMPLETED >> Off after 5sec + /// + private static SequenceActionResult RequestLaserUseWait(SequenceContext context, string id, SequenceActionResult param) + { + //var res = context.RetryUntilSuccess(() => ProcessManager.Instance.IsEnableLaserUse(), WELDING_TIMEOUT, MOTION_INTERVAL); + //if (res == E2.TIMEOUT) { + // Log.FuncE("EnableLaserUse Check Timeout!"); + // context.PutValue("AlarmCode", AlarmCode_PrismaticGun.ACS_STAGE_A_ENBALE_LASER_USE); + // return null; + //} else if (res == E2.CANCELLED) { + // Log.FuncE("EnableLaserUse Check Cancel!"); + // context.PutValue("AlarmCode", 0); + // return null; + //} + //ProcessManager.Instance.EnableLaserUse(false); + //Log.W("Laser Use Enable OK"); + + //// 반대쪽 Stage가 Running 중일때, 여기서 대기 + //Log.V($"{_targetCell.ToString()} Check ACS Welding Enable Check"); + + //res = context.RetryUntilSuccess(() => _motion.CheckACSWeldingEnable(_targetCell.WeldingStage), WELDING_TIMEOUT, MOTION_INTERVAL); + //if (res == E2.TIMEOUT) { + // Log.FuncE("Welding Enable Check Timeout!"); + // context.PutValue("AlarmCode", AlarmCode_PrismaticGun.ACS_WELDING_ENABLE); + // return null; + //} else if (res == E2.CANCELLED) { + // Log.FuncE("Welding Enable Check Cancel!"); + // context.PutValue("AlarmCode", 0); + // return null; + //} + //Log.V($"{_targetCell.ToString()} Check ACS Welding Enable Check Complete"); + + //레이저 관련 추가 필요 Jeongin///////////////////// + + //if (!_laser.GetLaserReady()) { + // Log.V($"{_targetCell.ToString()} Laser not Ready >> Laser On!!"); + // _laser.LaserOn(); + // Thread.Sleep(500); + //} + + //Log.V($"{_targetCell.ToString()} Laser Program Update Start"); + //res = context.RetryUntilSuccess(() => _laser.GetLaserReady(), WELDING_TIMEOUT, MOTION_INTERVAL); + //if (res == E2.TIMEOUT) { + // Log.FuncE("Laser Ready Check Timeout!"); + // context.PutValue("AlarmCode", AlarmCode_PrismaticGun.GET_LASER_READY); + // return null; + //} else if (res == E2.CANCELLED) { + // Log.FuncE("Laser Ready Check Cancel!"); + // context.PutValue("AlarmCode", 0); + // return null; + //} + + //_motion.SetLCILserOn(_LaserUse); + //Log.V($"Set ACS Laser LCI : {_LaserUse}"); + return SequenceAction.Ok(); + } + + private static SequenceActionResult StartACSWelding(SequenceContext context, string id, SequenceActionResult param) + { + if (!_motion.WeldingStart()) { + Log.FuncE("Welding Start Fail"); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.ACS_WELDING_COMP); //26.04.13잠시 주석 + return null; + } + + //ProcessManager.Instance.WeldingStart(_targetCell); + return SequenceAction.Ok(); + } + + private static SequenceActionResult WaitACSWeldingComp(SequenceContext context, string id, SequenceActionResult param) + { + Thread.Sleep(1000); + var res = context.RetryUntilSuccess(() => _motion.CheckWeldingComp(), WELDING_TIMEOUT, MOTION_INTERVAL); + if (res == E2.TIMEOUT) { + Log.FuncE("Welding Complete Check Timeout!"); + //context.PutValue("AlarmCode", AlarmCode_PrismaticGun.ACS_WELDING_COMP); //26.04.13 잠시 주석 + return null; + } else if (res == E2.CANCELLED) { + Log.FuncE("Welding Complete Check Cancel!"); + context.PutValue("AlarmCode", 0); + return null; + } + + //ProcessManager.Instance.WeldingComplete(_targetCell); + //Log.W($"TACT WELD CORE TIME >> {_targetCell.weldingData.TactTime_Welding.TotalSeconds}"); + + return SequenceAction.Ok(); + } + + private static SequenceActionResult CheckInterlock(SequenceContext context, string id, SequenceActionResult param) + { + Log.V($"Laser Interlock Start"); + + _motion.SetLCILserOn(false); + + Log.V($"Laser Interlock OK"); + return SequenceAction.Ok(); + } + + private static SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param) + { + Log.W($"Welding Sequence Complete"); + return SequenceAction.Ok(); + } + + private static void OnStopped(SequenceContext context) + { + //ProcessManager.Instance.EnableLaserUse(true); + _motion.WeldingStop(); + _motion.SetLCILserOn(false); + + Log.E("SeqWeldingCellStageA >> OnStopped !!!"); + } + + private static void OnForceError(SequenceContext context, string arg2) + { + var AlarmCode = context.GetValue("AlarmCode"); + if(AlarmCode > 0) + Log.E(context.AlarmAccured(AlarmCode)); + //ProcessManager.Instance.EnableLaserUse(true); + _motion.WeldingStop(); + _motion.SetLCILserOn(false); + + Log.E("SeqWeldingCellStageA >> OnForceError !!!"); + } + } +} \ No newline at end of file diff --git a/WeldingComponents/WeldingCommon/Settings/Gun/LineShotInLinesSetting.cs b/WeldingComponents/WeldingCommon/Settings/Gun/LineShotInLinesSetting.cs new file mode 100644 index 0000000..93f1779 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Settings/Gun/LineShotInLinesSetting.cs @@ -0,0 +1,22 @@ +using Aurora.Api; +using WeldingCommon.Process; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Text; +using System.Threading.Tasks; + +namespace WeldingCommon.Settings +{ + public class LineShotInLinesSetting : ISettingItem + { + public const int MaxCount = 20; + + public ManualLaserSetting SettingLineShotItems { get; set; } = new ManualLaserSetting(); + public LineShotInLinesSetting() + { + + } + } +} diff --git a/WeldingComponents/WeldingCommon/Settings/Gun/ManualLaserSetting.cs b/WeldingComponents/WeldingCommon/Settings/Gun/ManualLaserSetting.cs new file mode 100644 index 0000000..5b1c884 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Settings/Gun/ManualLaserSetting.cs @@ -0,0 +1,103 @@ +using Aurora.Api; +using Aurora.View; +using WeldingCommon.Process; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WeldingCommon.Settings +{ + public class ManualLaserSetting : ISettingItem + { + public const int Max = 20; + public ObservableCollection Lines { get; set; } = new ObservableCollection(); + public OneShotItem OneShots { get; set; } = new OneShotItem(); + public bool LaserIOUse { get; set; } = true; + public CameraLaserOffset CamLaserPositionOffset { get; set; } = new CameraLaserOffset(); + } + + public class LineShotItem : NotifyPropertyChangedBase, ICloneable + { + public string Name { get; set; } + public int Index { get => _Index; set => SetProperty(ref _Index, value); } + private int _Index = -1; + public double Ring { get => _Ring; set => SetProperty(ref _Ring, value); } + private double _Ring = 0; + public double Core { get => _Core; set => SetProperty(ref _Core, value); } + private double _Core = 0; + public double Velocity { get => _Velocity; set => SetProperty(ref _Velocity, value); } + private double _Velocity = 0; + public double Acc { get => _Acc; set => SetProperty(ref _Acc, value); } + private double _Acc = 0; + public double StartX { get => _StartX; set => SetProperty(ref _StartX, value); } + private double _StartX = 0; + public double StartY { get => _StartY; set => SetProperty(ref _StartY, value); } + private double _StartY = 0; + public double EndX { get => _EndX; set => SetProperty(ref _EndX, value); } + private double _EndX = 0; + public double EndY { get => _EndY; set => SetProperty(ref _EndY, value); } + private double _EndY = 0; + public double PositionZ { get => _PositionZ; set => SetProperty(ref _PositionZ, value); } + private double _PositionZ = 0; + public int YAxisType { get => _YAxisType; set => SetProperty(ref _YAxisType, value); } + private int _YAxisType = 0; + + [Browsable(false)] + public string State { get => _State; set => SetProperty(ref _State, value); } + private string _State = "Idle"; + public LineShotItem() + { + } + + public LineShotItem(LineShotItem SettingItem) + { + Index = SettingItem.Index; + StartX = SettingItem.StartX; + StartY = SettingItem.StartY; + EndX = SettingItem.EndX; + Velocity = SettingItem.Velocity; + Acc = SettingItem.Acc; + Ring = SettingItem.Ring; + Core = SettingItem.Core; + PositionZ = SettingItem.PositionZ; + } + + public object Clone() + { + return new LineShotItem(this); + } + } + + public class OneShotItem : NotifyPropertyChangedBase + { + public int ShotTime { get => _ShotTime; set => SetProperty(ref _ShotTime, value); } + private int _ShotTime; + public double ShotPower1 { get => _ShotPower1; set => SetProperty(ref _ShotPower1, value); } + private double _ShotPower1; + public double ShotPower2 { get => _ShotPower2; set => SetProperty(ref _ShotPower2, value); } + private double _ShotPower2; + + public OneShotItem() + { + } + } + + public class CameraLaserOffset : NotifyPropertyChangedBase + { + public double Y1UseOffsetX { get => _Y1UseOffsetX; set => SetProperty(ref _Y1UseOffsetX, value); } + private double _Y1UseOffsetX; + public double Y1UseOffsetY { get => _Y1UseOffsetY; set => SetProperty(ref _Y1UseOffsetY, value); } + private double _Y1UseOffsetY; + public double Y2UseOffsetX { get => _Y2UseOffsetX; set => SetProperty(ref _Y2UseOffsetX, value); } + private double _Y2UseOffsetX; + public double Y2UseOffsetY { get => _Y2UseOffsetY; set => SetProperty(ref _Y2UseOffsetY, value); } + private double _Y2UseOffsetY; + public CameraLaserOffset() + { + } + } +} diff --git a/WeldingComponents/WeldingCommon/Settings/Gun/TeachingPositionSetting.cs b/WeldingComponents/WeldingCommon/Settings/Gun/TeachingPositionSetting.cs new file mode 100644 index 0000000..a425dcc --- /dev/null +++ b/WeldingComponents/WeldingCommon/Settings/Gun/TeachingPositionSetting.cs @@ -0,0 +1,77 @@ +using Aurora.Api; +using Aurora.Api.Devices; +using Aurora.View; +using WeldingCommon.Process; // 26.04.13 +using OpenCvSharp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Permissions; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace WeldingCommon.Settings +{ + public enum eTeachingPosition + { + Load, + UnLoad, + SafetyPosition, + StageWeldingStartPos, + } + + public class TeachingPositionSetting : ISettingItem + { + public SettingPosition[] SettingPositions { get; set; } = new SettingPosition[Enum.GetValues(typeof(eTeachingPosition)).Length]; + + public TeachingPositionSetting() + { + SettingPositions[0] = new SettingPosition(eTeachingPosition.Load); + SettingPositions[1] = new SettingPosition(eTeachingPosition.UnLoad); + SettingPositions[2] = new SettingPosition(eTeachingPosition.SafetyPosition); + SettingPositions[3] = new SettingPosition(eTeachingPosition.StageWeldingStartPos); + } + + public SettingPosition Get(eTeachingPosition position) + { + int positionIndex = (int)position; + + if (positionIndex < 0 || positionIndex >= SettingPositions.Length) + return null; + + return SettingPositions[positionIndex]; + } + } + + public class SettingPosition : NotifyPropertyChangedBase + { + public string Name { get => _Name; set => SetProperty(ref _Name, value); } + private string _Name; + public double AxisX { get => _AxisX; set => SetProperty(ref _AxisX, value); } + private double _AxisX = 0.0; + public double AxisY1 { get => _AxisY1; set => SetProperty(ref _AxisY1, value); } + private double _AxisY1 = 0.0; + public double AxisY2 { get => _AxisY2; set => SetProperty(ref _AxisY2, value); } + private double _AxisY2 = 0.0; + public double AxisZ { get => _AxisZ; set => SetProperty(ref _AxisZ, value); } + private double _AxisZ = 0.0; + + public SettingPosition(eTeachingPosition position) + { + Name = $"{Enum.GetName(typeof(eTeachingPosition), position)}"; + AxisX = -999.0; + AxisY1 = -999.0; + AxisY2 = -999.0; + AxisZ = -999.0; + } + + public SettingPosition() + { + AxisX = -999.0; + AxisY1 = -999.0; + AxisY2 = -999.0; + AxisZ = -999.0; + } + } +} diff --git a/WeldingComponents/WeldingCommon/Settings/SystemParameter.cs b/WeldingComponents/WeldingCommon/Settings/SystemParameter.cs index b3f69eb..0987363 100644 --- a/WeldingComponents/WeldingCommon/Settings/SystemParameter.cs +++ b/WeldingComponents/WeldingCommon/Settings/SystemParameter.cs @@ -70,7 +70,7 @@ namespace WeldingCommon.Settings [ReadOnly(false)] [Category("System")] [DisplayName("WorkRecipeFile")] - public string WorkRecipeFile { get; set; } = SystemParamPath.WORK_RECIPE_FILE; + public string WorkRecipeFile { get; set; } = SystemParamPath.WORK_RECIPE_FILE; // 실제 데이터 파일 위치를 가리는 것 //LanguageType은 ILSOS의 언어 설정을 사용해야하나.. LASA 윈폼은 아래 LanguageType을 사용해서 변경해야할것으로 보임 [Browsable(false)] [ReadOnly(false)] @@ -112,22 +112,22 @@ namespace WeldingCommon.Settings [Category("Scout")] [InputFilePath] [DisplayName("ScoutImage File")] - public string ScannerFieldImageFile { get; set; } = SystemParamPath.SCANNER_FIELD_IMAGE_FILE_PATH; + public string ScannerFieldImageFile { get; set; } = SystemParamPath.SCANNER_FIELD_IMAGE_FILE_PATH; // 실제 데이터 파일 위치 가리키는 구조 [Browsable(true)] [ReadOnly(false)] [Category("Scout")] [DisplayName("ScoutJumpSpeed")] - public double FieldScanJumpSpeed { get; set; } = 4000; + public double FieldScanJumpSpeed { get; set; } = 4000; // 스캐너 Jump 속도 [Browsable(true)] [ReadOnly(false)] [Category("Scout")] [DisplayName("ScoutJumpDelay")] - public uint ScoutJumpDelay { get; set; } = 500; + public uint ScoutJumpDelay { get; set; } = 500; // Jump 후 대기 [Browsable(true)] [ReadOnly(false)] [Category("Scout")] [DisplayName("CameraExposureDelay")] - public uint CameraExposureDelay { get; set; } = 5; //msec + public uint CameraExposureDelay { get; set; } = 5; //msec // 촬영 전 대기 [Browsable(true)] [ReadOnly(false)] [Category("RCC Edge Parameter")] @@ -301,24 +301,24 @@ namespace WeldingCommon.Settings [ReadOnly(false)] [Category("Camera")] [DisplayName("CameraPixelSize")] - public double CameraPixelSize { get; set; } = 6.9; + public double CameraPixelSize { get; set; } = 6.9; // 이미지 -> 필드 좌표 변환 (µm) [Browsable(true)] [ReadOnly(false)] [Category("Camera")] [DisplayName("LensMagnification")] - public double LensMagnification { get; set; } = 0.3461; + public double LensMagnification { get; set; } = 0.3461; // 동일 [Browsable(false)] [ReadOnly(false)] [Category("Calibration")] [InputFilePath] [DisplayName("PowerCalibrationCenterBeamCSVFile")] - public string PowerCalibrationCenterBeamCSVFile { get; set; } = " "; + public string PowerCalibrationCenterBeamCSVFile { get; set; } = " "; // 파워 캘 csv [Browsable(false)] [ReadOnly(false)] [Category("Calibration")] [InputFilePath] [DisplayName("PowerCalibrationCenterBeamCSVFile")] - public string PowerCalibrationRingBeamCSVFile { get; set; } = " "; + public string PowerCalibrationRingBeamCSVFile { get; set; } = " "; // 파워 캘 CSV [Browsable(true)] [ReadOnly(false)] [Category("Weld")] diff --git a/WeldingComponents/WeldingCommon/Tools/Gun/CommonChecker.cs b/WeldingComponents/WeldingCommon/Tools/Gun/CommonChecker.cs new file mode 100644 index 0000000..cf62445 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Tools/Gun/CommonChecker.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WeldingCommon.Tools +{ + public static class CommonChecker + { + public static bool CheckInside(this double current, double target, double Gap) + { + if ((target - Gap) < current && current < (target + Gap)) + return true; + return false; + } + public static bool CheckInsideRelMinMax(this double current, double target, double minRel, double maxRel) + { + if ((target + minRel) < current && current < (target + maxRel)) + return true; + return false; + } + public static bool CheckInside(this int current, int target, int Gap) + { + if ((target - Gap) < current && current < (target + Gap)) + return true; + return false; + } + } +} diff --git a/WeldingComponents/WeldingCommon/Tools/Gun/CsvLogger.cs b/WeldingComponents/WeldingCommon/Tools/Gun/CsvLogger.cs new file mode 100644 index 0000000..a3e6517 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Tools/Gun/CsvLogger.cs @@ -0,0 +1,88 @@ +using WeldingCommon.Process; +using WeldingCommon.Settings; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; + +namespace WeldingCommon.Tools +{ + public class CsvLogger + { + private readonly object _fileLock = new object(); + + private readonly string _dirPath; // 디렉터리 보관 + private readonly string _fileNamePrefix; // 파일명 접두 (Default, 또는 인자) + private readonly string _dateFormat = "yyyyMMdd"; + private string _currentDate; // 마지막으로 쓴 날짜(yyyyMMdd) + private string _filePath; // 현재 쓰는 파일 경로 + + public CsvLogger(string filepath = null, string fileName = null) + { + _dirPath = string.IsNullOrWhiteSpace(filepath) ? AppDomain.CurrentDomain.BaseDirectory : filepath; + + Directory.CreateDirectory(_dirPath); + + _fileNamePrefix = string.IsNullOrWhiteSpace(fileName) ? "Default" : fileName; + + lock (_fileLock) { + UpdateFileDate(); + } + } + + private void UpdateFileDate() + { + string today = DateTime.Now.ToString(_dateFormat, CultureInfo.InvariantCulture); + if (_currentDate == today && !string.IsNullOrEmpty(_filePath)) + return; + + _currentDate = today; + string safeName = $"{_fileNamePrefix}_{_currentDate}.csv"; + _filePath = Path.Combine(_dirPath, safeName); + + if (!File.Exists(_filePath)) { + File.AppendAllText(_filePath, "Time,Lot_ID,Cell_ID,Ng,Judge,HeightMeas1,HeightMeas2,HeightMeas3,HeightMeas4,HeightMeas5,HeightMeas6,HeightMeas7,HeightMeas8\n", Encoding.UTF8); + } + } + + public void WriteLine(string str) + { + lock (_fileLock) { + UpdateFileDate(); + + string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); + string line = $"{time},{str}"; + File.AppendAllText(_filePath, line + Environment.NewLine, Encoding.UTF8); + } + } + + public void WriteLineCellData(PalletInfo Cell) + { + var sb = new StringBuilder(); + sb.Append(Cell.weldingData.LotId); sb.Append(","); + sb.Append(Cell.weldingData.CellId); sb.Append(","); + sb.Append(Cell.weldingData.NgJudge > 0); sb.Append(","); + sb.Append(Cell.weldingData.NgReason); sb.Append(","); + foreach (var heightMeas in Cell.weldingData.HeightMeasurements) { + sb.Append(heightMeas); sb.Append(","); + } + + WriteLine(sb.ToString()); + + //var inv = CultureInfo.InvariantCulture; + //string data = string.Join(",", Cell.weldingData.HeightMeasurements.Select(d => d.ToString("G", inv))); + //string line = $"{Cell.weldingData.LotId},{Cell.weldingData.CellId},{(Cell.weldingData.NgJudge > 0)},{Cell.weldingData.NgReason},{data}"; + //WriteLine(line); + } + + public string GetFilePath() + { + lock (_fileLock) { + UpdateFileDate(); + return _filePath; + } + } + } +} diff --git a/WeldingComponents/WeldingCommon/Tools/Gun/DualLogger.cs b/WeldingComponents/WeldingCommon/Tools/Gun/DualLogger.cs new file mode 100644 index 0000000..bac9802 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Tools/Gun/DualLogger.cs @@ -0,0 +1,67 @@ +using Aurora.Api; +using Aurora.Util.HislogPlus; +using WeldingCommon.Process; +using OpenCvSharp.Dnn; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace WeldingCommon.Tools +{ + public class DualLogger + { + private List _logList = new List(); + + public void AddLogger([CallerMemberName] string tag = null, string loggerName = null) { + _logList.Add(new LoggerInfo(tag, loggerName)); + } + + public void W(string log, eStage stage) => W(log, Enum.GetName(typeof(eStage), stage)); + public void E(string log, eStage stage) => E(log, Enum.GetName(typeof(eStage), stage)); + public void I(string log, eStage stage) => I(log, Enum.GetName(typeof(eStage), stage)); + public void V(string log, eStage stage) => V(log, Enum.GetName(typeof(eStage), stage)); + public void D(string log, eStage stage) => D(log, Enum.GetName(typeof(eStage), stage)); + + public void W(string log, string target = null) { + if (target == null) _logList.ForEach(t => t._log.W(log)); + else _logList.Where(t => t._loggerName.Contains(target)).FirstOrDefault()._log.W(log); + } + public void E(string log, string target = null) + { + if (target == null) _logList.ForEach(t => t._log.E(log)); + else _logList.Where(t => t._loggerName.Contains(target)).FirstOrDefault()._log.E(log); + } + public void V(string log, string target = null) + { + if (target == null) _logList.ForEach(t => t._log.V(log)); + else _logList.Where(t => t._loggerName.Contains(target)).FirstOrDefault()._log.V(log); + } + public void I(string log, string target = null) + { + if (target == null) _logList.ForEach(t => t._log.I(log)); + else _logList.Where(t => t._loggerName.Contains(target)).FirstOrDefault()._log.I(log); + } + public void D(string log, string target = null) + { + if (target == null) _logList.ForEach(t => t._log.D(log)); + else _logList.Where(t => t._loggerName.Contains(target)).FirstOrDefault()._log.D(log); + } + + private class LoggerInfo + { + public Logger _log; + public string _tag; + public string _loggerName; + + public LoggerInfo(string tag, string loggerName) + { + _tag = tag; + _loggerName = loggerName; + _log = new Logger(_tag, _loggerName); + } + } + } +} diff --git a/WeldingComponents/WeldingCommon/Tools/Gun/UnitConversion.cs b/WeldingComponents/WeldingCommon/Tools/Gun/UnitConversion.cs new file mode 100644 index 0000000..8998b5a --- /dev/null +++ b/WeldingComponents/WeldingCommon/Tools/Gun/UnitConversion.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WeldingCommon.Tools +{ + public static class UnitConversion + { + public static double ToPersent(this double Lpm) + { + if (Lpm == 0.0) + return 0.0; + return Lpm / 2.0; + } + public static double ToLPM(this double persent) + { + if (persent == 0.0) + return 0.0; + return persent * 2.0; + } + } +} diff --git a/WeldingComponents/WeldingCommon/Views/Calibration/UCScannerCalibrationViewModel.cs b/WeldingComponents/WeldingCommon/Views/Calibration/UCScannerCalibrationViewModel.cs index 1bd6968..48597ab 100644 --- a/WeldingComponents/WeldingCommon/Views/Calibration/UCScannerCalibrationViewModel.cs +++ b/WeldingComponents/WeldingCommon/Views/Calibration/UCScannerCalibrationViewModel.cs @@ -27,7 +27,9 @@ using WeldingCommon.Models; using WeldingCommon.Sequences; using WeldingCommon.Settings; using WeldingCommon.Utils; +using WeldingCommon.Process; using static CoreUnit.Control.UserControl.Canvas.WeldingParameterIDEditor; +using System.Diagnostics; //Process.Start namespace WeldingCommon.Views { @@ -348,7 +350,7 @@ namespace WeldingCommon.Views var fullPath = Path.Combine(filePath, "_device", "_scanner", "correXionPro.exe"); if (File.Exists(fullPath)) { - Process.Start(fullPath); + System.Diagnostics.Process.Start(fullPath); // 애매해서 } else { Log.I("correXionPro is not exist"); } diff --git a/WeldingComponents/WeldingCommon/Views/Recipes/Gun/UCMainRecipe.xaml b/WeldingComponents/WeldingCommon/Views/Recipes/Gun/UCMainRecipe.xaml new file mode 100644 index 0000000..0478710 --- /dev/null +++ b/WeldingComponents/WeldingCommon/Views/Recipes/Gun/UCMainRecipe.xaml @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +