/* * Copyright (c) 2025 LG Electronics Inc. * SPDX-License-Identifier: LicenseRef-LGE-Proprietary */ using Aurora.View; using VisionCommon; using VisionCalibrator; using System.Collections.Generic; using System.Windows; using System.Collections.ObjectModel; using VisionSequence.Setup; using VisionCommonUI; using VisionCommonUI.Resources; namespace VisionUI.Setup { /// /// 캘리브레이션 파라미터 뷰 모델 /// class CalParamViewModel : NotifyPropertyChangedBase, IUpdateRecipe { private SubSysInfo _SubSysInfo; private FovInfo _FovInfo; private FovRecipe _FovRecipe; private Calibrator _Calibrator; private ObservableCollection _PlanListItems; #region Binding Properties private CalRecipe _CalRecipe; /// 캘리브레이션 레시피 public CalRecipe CalRecipe { get => _CalRecipe; set { SetProperty(ref _CalRecipe, value); } } private CalFovRecipe _CalFovRecipe; /// 캘리브레이션 Fov 레시피 public CalFovRecipe CalFovRecipe { get => _CalFovRecipe; set { SetProperty(ref _CalFovRecipe, value); } } private RefPointRecipe _RefPointRecipe; /// 레퍼런스 포인트 레시피 public RefPointRecipe RefPointRecipe { get => _RefPointRecipe; set { SetProperty(ref _RefPointRecipe, value); } } #endregion /// /// 생성자 /// /// Fov 정보 public CalParamViewModel(FovInfo fovInfo) { _SubSysInfo = fovInfo.ToSubSysInfo(); _FovInfo = fovInfo; _CalRecipe = VisionRecipeManager.GetCalRecipe(_SubSysInfo); _FovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); _Calibrator = CalibratorManager.GetCalibrator(_FovInfo); _PlanListItems = new ObservableCollection(); } /// /// 저장 /// /// null public void DoSave(object o = null) { UpdateRecipeFromUI(); RecipeFileManager.SaveVisionRecipe(); } /// /// 캘리브레이션 결과 저장 /// /// 캘리브레이션 결과값들 리스트 /// 캘리브레이션 셋업 레시피 public void SetCalResult(List calResults, CalSetupRecipe calSetupRecipe) { Dictionary oldData = new Dictionary(); Dictionary newData = new Dictionary(); int fovCnt = VisionRecipeManager.GetFovCnt(_SubSysInfo); List _FovInfos = VisionRecipeManager.GetFovInfos(_SubSysInfo); List _FovRecipes = VisionRecipeManager.GetFovRecipes(_FovInfos); List camIds = VisionRecipeManager.GetCamIds(_FovRecipes); if (calSetupRecipe.isX() && calSetupRecipe.isY()) { for (int i = 0; i < camIds.Count; i++) { for (int j = 0; j < fovCnt; j++) { FovInfo fovInfo = VisionRecipeManager.GetFovInfo(_SubSysInfo, (eFovId)j); FovRecipe fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); if (fovRecipe.CamRecipe.CamId == camIds[i]) { oldData.Add(camIds[i] + " ErrRotation", fovRecipe.CalFovRecipe.ErrRotationX.Degree.ToString("F5")); oldData.Add(camIds[i] + " PixelSizeX", CoordUnitValueConverter.GetCoordUnitString(fovRecipe.CalFovRecipe.PixelSize.X)); oldData.Add(camIds[i] + " PixelSizeY", CoordUnitValueConverter.GetCoordUnitString(fovRecipe.CalFovRecipe.PixelSize.Y)); newData.Add(camIds[i] + " ErrRotation", calResults[i].ErrorRot.Degree.ToString("F5")); newData.Add(camIds[i] + " PixelSizeX", CoordUnitValueConverter.GetCoordUnitString(calResults[i].PixelSizeX)); newData.Add(camIds[i] + " PixelSizeY", CoordUnitValueConverter.GetCoordUnitString(calResults[i].PixelSizeY)); j = fovCnt; } } } } else if (calSetupRecipe.isX()) { for (int i = 0; i < camIds.Count; i++) { for (int j = 0; j < fovCnt; j++) { FovInfo fovInfo = VisionRecipeManager.GetFovInfo(_SubSysInfo, (eFovId)j); FovRecipe fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); if (fovRecipe.CamRecipe.CamId == camIds[i]) { oldData.Add(camIds[i] + " ErrRotation", fovRecipe.CalFovRecipe.ErrRotationX.Degree.ToString("F5")); oldData.Add(camIds[i] + " PixelSizeX", CoordUnitValueConverter.GetCoordUnitString(fovRecipe.CalFovRecipe.PixelSize.X)); newData.Add(camIds[i] + " ErrRotation", calResults[i].ErrorRot.Degree.ToString("F5")); newData.Add(camIds[i] + " PixelSizeX", CoordUnitValueConverter.GetCoordUnitString(calResults[i].PixelSizeX)); j = fovCnt; } } } } else if (calSetupRecipe.isY()) { for (int i = 0; i < camIds.Count; i++) { for (int j = 0; j < fovCnt; j++) { FovInfo fovInfo = VisionRecipeManager.GetFovInfo(_SubSysInfo, (eFovId)j); FovRecipe fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); if (fovRecipe.CamRecipe.CamId == camIds[i]) { oldData.Add(camIds[i] + " ErrRotation", fovRecipe.CalFovRecipe.ErrRotationX.Degree.ToString("F5")); oldData.Add(camIds[i] + " PixelSizeY", CoordUnitValueConverter.GetCoordUnitString(fovRecipe.CalFovRecipe.PixelSize.Y)); newData.Add(camIds[i] + " ErrRotation", calResults[i].ErrorRot.Degree.ToString("F5")); newData.Add(camIds[i] + " PixelSizeY", CoordUnitValueConverter.GetCoordUnitString(calResults[i].PixelSizeY)); j = fovCnt; } } } } if (calSetupRecipe.isT()) { oldData.Add("ThetaOriginX", CoordUnitValueConverter.GetCoordUnitString(CalRecipe.ThetaOrigin.X)); oldData.Add("ThetaOriginY", CoordUnitValueConverter.GetCoordUnitString(CalRecipe.ThetaOrigin.Y)); // ThetaOrigin은 Cam과 상관 없이 공통된(동일한)값이므로 List의 0번째 값 사용 newData.Add("ThetaOriginX", CoordUnitValueConverter.GetCoordUnitString(calResults[0].ThetaOrigin.X)); newData.Add("ThetaOriginY", CoordUnitValueConverter.GetCoordUnitString(calResults[0].ThetaOrigin.Y)); } if (MessageBoxUtil.ShowMessageBoxSaveData(oldData, newData, string.Format(StrTokens.MSG_S_ConfirmSaveCalData)) == MessageBoxResult.Yes) { if (calSetupRecipe.isX() && calSetupRecipe.isY()) { for (int i = 0; i < fovCnt; i++) { FovInfo fovInfo = VisionRecipeManager.GetFovInfo(_SubSysInfo, (eFovId)i); FovRecipe fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); var calFovRecipe = fovRecipe.CalFovRecipe; for (int j = 0; j < camIds.Count; j++) { if (fovRecipe.CamRecipe.CamId == camIds[j]) { calFovRecipe.ErrRotationX = calResults[j].ErrorRot.Clone() as Angle; calFovRecipe.PixelSize.X = calResults[j].PixelSizeX; calFovRecipe.PixelSize.Y = calResults[j].PixelSizeY; } } } } else if (calSetupRecipe.isX()) { for (int i = 0; i < fovCnt; i++) { FovInfo fovInfo = VisionRecipeManager.GetFovInfo(_SubSysInfo, (eFovId)i); FovRecipe fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); var calFovRecipe = fovRecipe.CalFovRecipe; for (int j = 0; j < camIds.Count; j++) { if (fovRecipe.CamRecipe.CamId == camIds[j]) { calFovRecipe.ErrRotationX = calResults[j].ErrorRot.Clone() as Angle; calFovRecipe.PixelSize.X = calResults[j].PixelSizeX; } } } } else if (calSetupRecipe.isY()) { for (int i = 0; i < fovCnt; i++) { FovInfo fovInfo = VisionRecipeManager.GetFovInfo(_SubSysInfo, (eFovId)i); FovRecipe fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo); var calFovRecipe = fovRecipe.CalFovRecipe; for (int j = 0; j < camIds.Count; j++) { if (fovRecipe.CamRecipe.CamId == camIds[j]) { calFovRecipe.ErrRotationX = calResults[j].ErrorRot.Clone() as Angle; calFovRecipe.PixelSize.Y = calResults[j].PixelSizeY; } } } } if (calSetupRecipe.isT()) { var calRecipe = VisionRecipeManager.GetCalRecipe(_SubSysInfo); calRecipe.ThetaOrigin.X = calResults[0].ThetaOrigin.X; calRecipe.ThetaOrigin.Y = calResults[0].ThetaOrigin.Y; } RecipeFileManager.SaveVisionRecipe(); UpdateRecipeFromFile(); } } public void RefreshVisionRecipes() { _CalRecipe = VisionRecipeManager.GetCalRecipe(_SubSysInfo); _FovRecipe = VisionRecipeManager.GetFovRecipe(_FovInfo); _Calibrator?.RefreshFovRecipe(_FovRecipe); eCamId camId = _FovRecipe.CamRecipe.CamId; } public void UpdateRecipeFromFile() { var calRecipe = VisionRecipeManager.GetCalRecipe(_SubSysInfo); CalRecipe = calRecipe.Clone(); var fovRecipe = VisionRecipeManager.GetFovRecipe(_FovInfo); CalFovRecipe = fovRecipe.CalFovRecipe.Clone(); RefPointRecipe = fovRecipe.RefPointRecipe.Clone(); } public void UpdateRecipeFromUI() { var calRecipe = VisionRecipeManager.GetCalRecipe(_SubSysInfo); CalRecipe.CopyTo(calRecipe); var fovRecipe = VisionRecipeManager.GetFovRecipe(_FovInfo); CalFovRecipe.CopyTo(fovRecipe.CalFovRecipe); RefPointRecipe.CopyTo(fovRecipe.RefPointRecipe); } } }