/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using Aurora.Api; using VisionCommon; using System.Windows.Input; using Aurora.View; using System; using VisionDirector; using System.Windows; using VisionSequence.Aligner; using VisionCommonUI; using System.Threading.Tasks; using VisionCommonUI.Resources; using VisionSequence; using System.Collections.Generic; namespace VisionUI.Aligner { /// /// 얼라인 세팅 뷰 모델 /// class AlignSettingViewModel : Aurora.View.NotifyPropertyChangedBase { private Logger _Logger = new Logger(typeof(AlignSettingViewModel).Name); private SubSysInfo _SubSysInfo; private AlignInfo _CurrentAlignInfo; private AlignRecipe _CurrentAlignRecipe; /// 얼라인 시퀀스 버튼 커맨드 public ICommand BtnCmdAlign { get; } /// 시퀀스 다이어그램 보여주는 버튼 커맨드 public ICommand BtnCmdShowDiagram { get; } /// /// 생성자 /// /// 서브시스템 정보 public AlignSettingViewModel(SubSysInfo subSysInfo) { _SubSysInfo = subSysInfo; BtnCmdAlign = new DelegateCommand(Align); BtnCmdShowDiagram = new DelegateCommand(ShowDiagram); } /// /// 현재 얼라인 정보 설정 /// /// 얼라인 Id public void SetCurrentAlignInfo(eAlignId alignId) { _CurrentAlignInfo = VisionRecipeManager.GetAlignInfo(_SubSysInfo.UnitId, _SubSysInfo.SubSysId, alignId); _CurrentAlignRecipe = VisionRecipeManager.GetAlignRecipe(_CurrentAlignInfo); } private void Align(object obj) { StartAlignProcSeq(); } private void StartAlignProcSeq() { try { var myDisplayType = eDisplayType.Main_1; // 얼라인 결과를 바인딩할 메인 화면 타입을 지정해서 사용 SeqParamsBase seqParams = null; ISequence seq = null; var procFovType = _CurrentAlignRecipe.ProcParams.ProcFovType; if (procFovType == eProcFovType.C1_F1_AP2_A2 || procFovType == eProcFovType.C1_F1_SPN_AN) { var refDistParam = AlignSeqUtil.GetDefaultRefDistParam(); seqParams = new AlignProcSeqParams_PN_AN(_CurrentAlignInfo, refDistParam); seq = VisionEnv.AuroraEnv.SequenceEntry[VisionKeys.AlignProcSeqKey_PN_AN]; } else { seqParams = AlignProcSeqManager.GetAlignProcSeqParams(_CurrentAlignInfo, null, myDisplayType); seq = AlignProcSeqManager.GetSeq(_CurrentAlignInfo); } seqParams.SeqMode = eSeqMode.Manual; if (seq.RunState == SequenceRunState.Running) { seq.EmergencyStop(); } seq.Start(seqParams, OnAlignProcSeqCompleted); } catch (Exception e) { _Logger.FuncE(e.Message); } } private void OnAlignProcSeqCompleted(SequenceActionResult seqResult) { try { if (_CurrentAlignRecipe.ProcParams.ProcFovType == eProcFovType.C1_F1_AP2_A2 || _CurrentAlignRecipe.ProcParams.ProcFovType == eProcFovType.C1_F1_SPN_AN) { var alignResult = seqResult.Param as Dictionary; } else { var alignResult = seqResult.Param as AlignResult; CheckManualMoveDelta(alignResult); } } catch (Exception e) { _Logger.FuncE(e.Message); } } private void ShowDiagram(object obj) { try { if (SegDiagramManager.SeqDiagram != null && SegDiagramManager.SeqDiagram.IsLoaded) { return; } var myDisplayType = eDisplayType.Main_1; // 얼라인 결과를 바인딩할 메인 화면 타입을 지정해서 사용 SeqParamsBase seqParams = null; ISequence seq = null; var procFovType = _CurrentAlignRecipe.ProcParams.ProcFovType; string seqName; if (procFovType == eProcFovType.C1_F1_AP2_A2 || procFovType == eProcFovType.C1_F1_SPN_AN) { var refDistParam = AlignSeqUtil.GetDefaultRefDistParam(); seqParams = new AlignProcSeqParams_PN_AN(_CurrentAlignInfo, refDistParam); seqName = VisionKeys.AlignProcSeqKey_PN_AN; seq = VisionEnv.AuroraEnv.SequenceEntry[VisionKeys.AlignProcSeqKey_PN_AN]; } else { seqParams = AlignProcSeqManager.GetAlignProcSeqParams(_CurrentAlignInfo, null, myDisplayType); seqName = AlignProcSeqManager.GetSeqName(_CurrentAlignInfo); seq = AlignProcSeqManager.GetSeq(_CurrentAlignInfo); } seqParams.SeqMode = eSeqMode.Manual; seq.RunStateChanged += DiagramRunStateChanged; SegDiagramManager.Show(seqName, seqParams); SegDiagramManager.SeqDiagram.Closed += SeqDiagram_Closed; } catch (Exception e) { _Logger.FuncE(e.Message); } } private void SeqDiagram_Closed(object sender, EventArgs e) { ISequence seq = AlignProcSeqManager.GetSeq(_CurrentAlignInfo); seq.RunStateChanged -= DiagramRunStateChanged; SegDiagramManager.SeqDiagram.Closed -= SeqDiagram_Closed; } /// /// 시퀀스 다이어그램 실행시 상태 변경 이벤트 핸들러 메서드 /// /// 객체 /// 이벤트 public void DiagramRunStateChanged(object sender, (string sequenceId, SequenceRunState state) e) { if (e.state == SequenceRunState.Finish) { var seq = sender as ISequence; if (_CurrentAlignRecipe.ProcParams.ProcFovType == eProcFovType.C1_F1_AP2_A2 || _CurrentAlignRecipe.ProcParams.ProcFovType == eProcFovType.C1_F1_SPN_AN) { var alignResults = seq.SearchContext(string.Format( VisionContextKeys.CNTXT_KEY_ALIGN_RESULTS, _CurrentAlignInfo.GetKey())) as Dictionary; } else { var alignResult = seq.SearchContext(string.Format( VisionContextKeys.CNTXT_KEY_ALIGN_RESULT_WITH_OFFSET, _CurrentAlignInfo.GetKey())) as AlignResult; CheckManualMoveDelta(alignResult); } } } private void CheckManualMoveDelta(AlignResult alignResult) { if (alignResult == null) { MessageBoxUtil.ShowMessageBoxError( string.Format(StrTokens.MSG_E_AlignResultIsNull)); return; } if (alignResult.Status == AlignStatus.OK || alignResult.Status == AlignStatus.F_OK || alignResult.Status == AlignStatus.RETRY) { var delta = alignResult.Delta; var result = MessageBoxUtil.ShowMessageBoxQuestion( string.Format(StrTokens.MSG_Q_ConfirmMoveByAlignData, ConvertAlignDelta(delta))); if (result == MessageBoxResult.Yes) { var alignDirector = AlignDirectorManager.Instance.GetDirector(_SubSysInfo); var motionDelta = alignDirector.ApplyDirection(delta.ToPosition()); Task.Run(() => { EquipAdapter.Instance.AlignMotionManager.RelMove(_SubSysInfo, motionDelta); }); } } } private string ConvertAlignDelta(AlignDelta alignDelta) { if (VisionSettingManager.VisionSetting.CoordUnit == eCoordUnit.UM) { return alignDelta.ToStringUm(); } return alignDelta.ToString(); } } }