667 lines
30 KiB
C#
667 lines
30 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.Api.Devices;
|
|
using Aurora.Api.Manager;
|
|
using Aurora.View;
|
|
using AuroraLaser;
|
|
using AuroraLaserScanner;
|
|
using CoreUnit.Scanner.UserControl.ScannerCanvas;
|
|
using Microsoft.Win32;
|
|
using MilUI;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Configuration;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reactive.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Input;
|
|
using System.Windows.Threading;
|
|
using VisionCommon;
|
|
using WeldingCommon.Sequences;
|
|
using WeldingCommon.Settings;
|
|
using WeldingCommon.Utils;
|
|
|
|
namespace WeldingCommon.Views
|
|
{
|
|
public class UCScannerCalibrationViewModel : NotifyPropertyChangedBase
|
|
{
|
|
private readonly Logger Log = new Logger("UCScannerCalibrationViewModel");
|
|
|
|
public ICommand CMD_VisibleChanged { get; }
|
|
|
|
public ICommand CMD_ApplyGridItems { get; }
|
|
public ICommand CMD_SaveDataFile { get; }
|
|
public ICommand CMD_RunCorreXionPro { get; }
|
|
|
|
public ICommand CMD_RunMarkGrid { get; }
|
|
public ICommand CMD_StopMarkGrid { get; }
|
|
|
|
public ICommand CMD_RunScannerCalibration { get; }
|
|
public ICommand CMD_StopScannerCalibration { get; }
|
|
public ICommand CMD_FindPattern { get; }
|
|
public ICommand CMD_CalculateDistance { get; }
|
|
public ICommand CMD_GetCenterCnt { get; }
|
|
|
|
//public ICommand CMD_ChangedCaltype { get; }
|
|
//public ICommand CMD_SeqStop { get; }
|
|
|
|
private readonly IAuroraEnvironment _Aurora;
|
|
private SystemParameter _SystemParameter;
|
|
private readonly Scanner _Scanner;
|
|
private readonly ILaserDevice _Laser;
|
|
private readonly ScannerConfig _ScannerConfig;
|
|
|
|
private ISequence _SeqMarkGrid;
|
|
private bool _IsSequenceRunning_MarkGrid;
|
|
public bool IsSequenceRunning_MarkGrid { get => _IsSequenceRunning_MarkGrid; set => SetProperty(ref _IsSequenceRunning_MarkGrid, value); }
|
|
|
|
private ISequence _SeqScannerCalibration;
|
|
private bool _IsSequenceRunning_ScannerCalibration;
|
|
public bool IsSequenceRunning_ScannerCalibration { get => _IsSequenceRunning_ScannerCalibration; set => SetProperty(ref _IsSequenceRunning_ScannerCalibration, value); }
|
|
|
|
// Support VisionCorrectionList Selection.
|
|
private ObservableCollection<CorrectionUnit> _SelectedVisionCorrectionList;
|
|
public ObservableCollection<CorrectionUnit> SelectedVisionCorrectionList { get => _SelectedVisionCorrectionList; set => SetProperty(ref _SelectedVisionCorrectionList, value); }
|
|
|
|
private ObservableCollection<CorrectionUnit> _VisionCorrectionList;
|
|
public ObservableCollection<CorrectionUnit> VisionCorrectionList { get => _VisionCorrectionList; set => SetProperty(ref _VisionCorrectionList, value); }
|
|
private ObservableCollection<PatternCorrectionUnit> _PatternCorrectionList;
|
|
public ObservableCollection<PatternCorrectionUnit> PatternCorrectionList { get => _PatternCorrectionList; set => SetProperty(ref _PatternCorrectionList, value); }
|
|
|
|
// Correction Param
|
|
private int _GridRowCount;
|
|
public int GridRowCount { get => _GridRowCount; set => SetProperty(ref _GridRowCount, value); }
|
|
private int _GridColumnCount;
|
|
public int GridColumnCount { get => _GridColumnCount; set => SetProperty(ref _GridColumnCount, value); }
|
|
private float _UnitLength;
|
|
public float UnitLength { get => _UnitLength; set => SetProperty(ref _UnitLength, value); }
|
|
private float _TiltingDegree;
|
|
public float TiltingDegree { get => _TiltingDegree; set => SetProperty(ref _TiltingDegree, value); }
|
|
|
|
private double _CurrentX;
|
|
public double CurrentX { get => _CurrentX; set => SetProperty(ref _CurrentX, value); }
|
|
private double _CurrentY;
|
|
public double CurrentY { get => _CurrentY; set => SetProperty(ref _CurrentY, value); }
|
|
private bool _Is1StepCalibration;
|
|
public bool Is1StepCalibration { get => _Is1StepCalibration; set => SetProperty(ref _Is1StepCalibration, value); }
|
|
private int _RetryNum;
|
|
public int RetryNum { get => _RetryNum; set => SetProperty(ref _RetryNum, value); }
|
|
|
|
private int _SelectedRowIndex;
|
|
public int SelectedRowIndex { get => _SelectedRowIndex; set => SetProperty(ref _SelectedRowIndex, value); }
|
|
// Vision Param
|
|
private double _MPosOffsetX;
|
|
public double MPosOffsetX { get => _MPosOffsetX; set => SetProperty(ref _MPosOffsetX, value); }
|
|
private double _MPosOffsetY;
|
|
public double MPosOffsetY { get => _MPosOffsetY; set => SetProperty(ref _MPosOffsetY, value); }
|
|
|
|
private double _OffsetThreshold;
|
|
public double OffsetThreshold { get => _OffsetThreshold; set => SetProperty(ref _OffsetThreshold, value); }
|
|
|
|
// Vision Param - Calibration Type
|
|
private bool _IsVisionCalibration;
|
|
public bool IsVisionCalibration { get => _IsVisionCalibration; set => SetProperty(ref _IsVisionCalibration, value); }
|
|
|
|
// Laser Param
|
|
private double _MarkPower;
|
|
public double MarkPower { get => _MarkPower; set => SetProperty(ref _MarkPower, value); }
|
|
private double _MarkSpeed;
|
|
public double MarkSpeed { get => _MarkSpeed; set => SetProperty(ref _MarkSpeed, value); }
|
|
private double _MarkLength;
|
|
public double MarkLength { get => _MarkLength; set => SetProperty(ref _MarkLength, value); }
|
|
private bool _LaserStatus;
|
|
public bool LaserStatus { get => _LaserStatus; set => SetProperty(ref _LaserStatus, value); }
|
|
private bool _IsModulation;
|
|
public bool IsModulation { get => _IsModulation; set => SetProperty(ref _IsModulation, value); }
|
|
private uint _Frequency;
|
|
public uint Frequency { get => _Frequency; set => SetProperty(ref _Frequency, value); }
|
|
private uint _PulseDuration;
|
|
public uint PulseDuration { get => _PulseDuration; set => SetProperty(ref _PulseDuration, value); }
|
|
|
|
//Pixel Resolution
|
|
private bool _IsGrabLiveLimage;
|
|
public bool IsGrabLiveLimage { get => _IsGrabLiveLimage; set => SetProperty(ref _IsGrabLiveLimage, value); }
|
|
private double _ReferenceDistance;
|
|
public double ReferenceDistance { get => _ReferenceDistance; set => SetProperty(ref _ReferenceDistance, value); }
|
|
private double _PixelDistanceMin;
|
|
public double PixelDistanceMin { get => _PixelDistanceMin; set => SetProperty(ref _PixelDistanceMin, value); }
|
|
private double _PixelDistanceMax;
|
|
public double PixelDistanceMax { get => _PixelDistanceMax; set => SetProperty(ref _PixelDistanceMax, value); }
|
|
private double _DistanceAverage;
|
|
public double DistanceAverage { get => _DistanceAverage; set => SetProperty(ref _DistanceAverage, value); }
|
|
private double _LensMagnification;
|
|
public double LensMagnification { get => _LensMagnification; set => SetProperty(ref _LensMagnification, value); }
|
|
|
|
private FovInfo _FovInfo;
|
|
private CameraAgentBase _CameraAgent;
|
|
private PatternAgentBase _PatternAgent;
|
|
private object _GrabImage;
|
|
private PatternResult _PatternResult;
|
|
private readonly DispatcherTimer _MonitorTimer;
|
|
//private string _CalibrationType;
|
|
|
|
public UCScannerCalibrationViewModel(IAuroraEnvironment aurora)
|
|
{
|
|
_Aurora = aurora;
|
|
|
|
_SystemParameter = aurora.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
|
|
|
|
_Scanner = _Aurora.DeviceManager[CommonDeviceIds.Scanner] as Scanner;
|
|
_Laser = _Aurora.DeviceManager[CommonDeviceIds.Laser] as ILaserDevice;
|
|
_ScannerConfig = _Aurora.DeviceManager.GetDeviceConfig(_Scanner.DeviceId) as ScannerConfig;
|
|
|
|
_SeqMarkGrid = _Aurora.SequenceEntry[CommonSequenceIds.SeqMarkGrid] as ISequence;
|
|
_SeqScannerCalibration = _Aurora.SequenceEntry[CommonSequenceIds.SeqScannerCalibration] as ISequence;
|
|
|
|
_FovInfo = VisionRecipeManager.GetFovInfos().FirstOrDefault();
|
|
|
|
_CameraAgent = CameraAgentManager.GetCameraAgent(_FovInfo);
|
|
//FovInfo는 UI 생성자를 통해 전달된 Params의 FovInfo를 사용한다.
|
|
_PatternAgent = PatternAgentManager.GetAgent(_FovInfo);
|
|
|
|
//GrabImageBuffer를 Update할 필요가 있으면 아래 코드 사용
|
|
//IpAdapter.Instance.IpEnvironment.FreeImage(_GrabImage);
|
|
_GrabImage = _CameraAgent.CloneImageBuffer();
|
|
|
|
VisionCorrectionList = new ObservableCollection<CorrectionUnit>();
|
|
SelectedVisionCorrectionList = new ObservableCollection<CorrectionUnit>();
|
|
PatternCorrectionList = new ObservableCollection<PatternCorrectionUnit>();
|
|
|
|
InitVariable();
|
|
|
|
CMD_VisibleChanged = new DelegateCommand(VisibleChanged);
|
|
CMD_ApplyGridItems = new DelegateCommand(PerformCmdApplyGridItems);
|
|
CMD_SaveDataFile = new DelegateCommand(PerformCmdSaveDataFile);
|
|
CMD_RunCorreXionPro = new DelegateCommand(PerformCmdRunCorreXionPro);
|
|
CMD_RunMarkGrid = new DelegateCommand(PerformCmdRunMarkGrid);
|
|
CMD_StopMarkGrid = new DelegateCommand(PerformCmdStopMarkGrid);
|
|
CMD_RunScannerCalibration = new DelegateCommand(PerformCmdRunScannerCalibration);
|
|
CMD_StopScannerCalibration = new DelegateCommand(PerformCmdStopScannerCalibration);
|
|
CMD_FindPattern = new DelegateCommand(PerformCmdFindPattern);
|
|
CMD_CalculateDistance = new DelegateCommand(PerformCmdCalculateDistance);
|
|
CMD_GetCenterCnt = new DelegateCommand(PerformCmdGetCenterCount);
|
|
|
|
_MonitorTimer = new DispatcherTimer();
|
|
_MonitorTimer.Tick += OnMonitoring;
|
|
_MonitorTimer.Interval = TimeSpan.FromMilliseconds(100);
|
|
|
|
// ian0513, 아래 Sequence 에서 보내 주는 걸로만 event 처리 하지 말고, event 등록 해서 처리 되도록 하는 것이 명확함.
|
|
_Aurora.EventObservable.AsObservable(CommonSequenceIds.SeqScannerCalibration)
|
|
.ObserveOnDispatcher().Subscribe(x => OnUpdateCorrectionTable(x));
|
|
}
|
|
|
|
private void InitVariable()
|
|
{
|
|
GridRowCount = 13;
|
|
GridColumnCount = 13;
|
|
UnitLength = 10;
|
|
TiltingDegree = 0;
|
|
|
|
MPosOffsetX = 0;
|
|
MPosOffsetY = 0;
|
|
OffsetThreshold = 0.01;
|
|
IsVisionCalibration = true;
|
|
|
|
MarkPower = 10;
|
|
MarkSpeed = 100;
|
|
MarkLength = 10;
|
|
|
|
LaserStatus = false;
|
|
|
|
Frequency = 10000;
|
|
PulseDuration = 10000;
|
|
//InitializeDataGridViewItem(GridColumnCount, GridRowCount, UnitLength, TiltingDegree);
|
|
|
|
}
|
|
|
|
private void VisibleChanged(object obj)
|
|
{
|
|
bool visible = (bool)obj;
|
|
if (visible) {
|
|
_MonitorTimer.Start();
|
|
} else {
|
|
_MonitorTimer.Stop();
|
|
}
|
|
}
|
|
|
|
private void OnMonitoring(object sender, EventArgs e)
|
|
{
|
|
double xPos, yPos;
|
|
if (_Scanner != null) {
|
|
_Scanner.GetXYPos(out xPos, out yPos);
|
|
CurrentX = xPos;
|
|
CurrentY = yPos;
|
|
}
|
|
|
|
if (_Laser.GetLaserReady()) {
|
|
LaserStatus = true;
|
|
} else {
|
|
LaserStatus = false;
|
|
}
|
|
}
|
|
|
|
private void OnUpdateCorrectionTable(EventMessage obj)
|
|
{
|
|
var updateDataGridItem = obj.Param as UpdateDataGridItem;
|
|
|
|
if (updateDataGridItem != null) {
|
|
VisionCorrectionList[updateDataGridItem.Upositionindex].VisionX = updateDataGridItem.UVisionX;
|
|
VisionCorrectionList[updateDataGridItem.Upositionindex].VisionY = updateDataGridItem.UVisionY;
|
|
}
|
|
}
|
|
|
|
private void PerformCmdApplyGridItems(object obj)
|
|
{
|
|
// 1. 원래 있던 data table 을 전부 초기화한다
|
|
// 2. 새로 적용된 row count 와 column count 로 새로 data table 을 만든다
|
|
// 3. VisionX 와 VisionY 는 0값을 넣어둔다. Calibration에서 패턴매칭 값을 이벤트로 받아와서 업데이트한다.
|
|
try {
|
|
InitializeDataGridViewItem(GridColumnCount, GridRowCount, UnitLength, TiltingDegree);
|
|
} catch (Exception ex) {
|
|
MessageUtil.ShowErrorToast(ex.Message);
|
|
}
|
|
}
|
|
|
|
private void PerformCmdSaveDataFile(object obj)
|
|
{
|
|
// 저장양식이 정해지면 업데이트하자
|
|
// 이전 버전은 database 에 저장하게 되어있음
|
|
try {
|
|
SaveFileDialog dlg = new SaveFileDialog();
|
|
dlg.InitialDirectory = @"D:\LASA.eqpdata\Scanner\Correction";
|
|
dlg.DefaultExt = "dat";
|
|
dlg.Filter = "data 파일 (*.dat)|*.dat";
|
|
dlg.Title = "data 파일 저장";
|
|
|
|
if (dlg.ShowDialog() == true) {
|
|
using (StreamWriter sw = new StreamWriter(dlg.FileName, false, Encoding.Default)) {
|
|
string oldCorrectionFile = IsVisionCalibration ?
|
|
_Scanner.Config.CorrectionFile : _Scanner.Config.LaserCorrectionFile;
|
|
FileInfo oldCorrectionFileInfo = new FileInfo(oldCorrectionFile);
|
|
|
|
sw.WriteLine(string.Format("OLDCTFILE\t= {0}", oldCorrectionFileInfo.Name));
|
|
sw.WriteLine(string.Format("NEWCTFILE\t= NewCorrectionTable.ct5"));
|
|
sw.WriteLine(string.Format("\r\nTOLERANCE\t= 1.0"));
|
|
|
|
uint newCal = (uint)Math.Round(_Scanner.Config.ScaleXYFactor);
|
|
|
|
sw.WriteLine(string.Format("\r\nNEWCAL\t= {0}", newCal));
|
|
//sw.WriteLine(string.Format("LIMITS"));
|
|
sw.WriteLine(string.Format("\r\n// RTC-X [Bit] RTC-Y[Bit] REAL-X[mm] REAL-Y[mm]\r\n"));
|
|
|
|
double visionX = 0;
|
|
double visionY = 0;
|
|
double realX = 0;
|
|
double realY = 0;
|
|
double tempX = 0;
|
|
double tempY = 0;
|
|
|
|
for (int i = 0; i < GridRowCount * GridColumnCount; i++) {
|
|
visionX = Convert.ToDouble(VisionCorrectionList[i].VisionX);
|
|
visionY = Convert.ToDouble(VisionCorrectionList[i].VisionY);
|
|
|
|
realX = Convert.ToDouble(VisionCorrectionList[i].MasterX);
|
|
realY = Convert.ToDouble(VisionCorrectionList[i].MasterY);
|
|
|
|
sw.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}", visionX, visionY, realX, realY));
|
|
|
|
//string finalX;
|
|
//string finalY;
|
|
//if (tempX == 0)
|
|
//{
|
|
// finalX = "0,0";
|
|
//}
|
|
//else
|
|
//{
|
|
// string sX;
|
|
// string upperX;
|
|
// string lowerX;
|
|
// if ((Math.Round(tempX, 3) - Math.Truncate(tempX)) == 0)
|
|
// {
|
|
// sX = Convert.ToString(Math.Truncate(tempX));
|
|
// upperX = sX;
|
|
// lowerX = "0";
|
|
// }
|
|
// else
|
|
// {
|
|
// //sX = Convert.ToString(Math.Round(tempX, 3));
|
|
// sX = Math.Round(tempX, 3).ToString("f3");
|
|
|
|
// upperX = sX.Substring(0, sX.IndexOf("."));
|
|
// lowerX = sX.Substring(sX.IndexOf(".") + 1);
|
|
// }
|
|
|
|
// finalX = upperX + "," + lowerX;
|
|
//}
|
|
//if (tempY == 0)
|
|
//{
|
|
// finalY = "0,0";
|
|
//}
|
|
//else
|
|
//{
|
|
// string sY;
|
|
// string upperY;
|
|
// string lowerY;
|
|
// if ((Math.Round(tempY, 3) - Math.Truncate(tempY)) == 0)
|
|
// {
|
|
// sY = Convert.ToString(Math.Truncate(tempY));
|
|
// upperY = sY;
|
|
// lowerY = "0";
|
|
// }
|
|
// else
|
|
// {
|
|
// //sY = Convert.ToString(Math.Round(tempY, 3));
|
|
// sY = Math.Round(tempY, 3).ToString("f3");
|
|
// upperY = sY.Substring(0, sY.IndexOf("."));
|
|
// lowerY = sY.Substring(sY.IndexOf(".") + 1);
|
|
// }
|
|
|
|
// finalY = upperY + "," + lowerY;
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception ex) {
|
|
Log.E(string.Format(ex.Message));
|
|
}
|
|
}
|
|
|
|
private void PerformCmdRunCorreXionPro(object obj)
|
|
{
|
|
var filePath = ConfigurationManager.AppSettings.Get("DATA_PATH");
|
|
var fullPath = Path.Combine(filePath, "_device", "_scanner", "correXionPro.exe");
|
|
|
|
if (File.Exists(fullPath)) {
|
|
Process.Start(fullPath);
|
|
} else {
|
|
Log.I("correXionPro is not exist");
|
|
}
|
|
}
|
|
|
|
private void PerformCmdRunMarkGrid(object obj)
|
|
{
|
|
if (_ScannerConfig.UseMarkingOnTheFly == true) {
|
|
MessageUtil.ShowWarningToast(string.Format("Please Check Marking on the Fly(MOTF)"));
|
|
return;
|
|
}
|
|
|
|
if (VisionCorrectionList.Count <= 0 || LaserStatus == false) {
|
|
MessageUtil.ShowWarningToast(string.Format("Please Check DataCorrection or LaserStatus or LaserCalType"));
|
|
return;
|
|
}
|
|
|
|
var result = MessageUtil.ShowYesNoMessageDialog("Laser Calibration", "Start Laser Calibration Sequence?");
|
|
if (result == false) {
|
|
return;
|
|
}
|
|
|
|
if (_SeqMarkGrid.RunState == SequenceRunState.Running) {
|
|
MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "_SeqMarkGrid"));
|
|
return;
|
|
}
|
|
|
|
var param = new SeqMarkGrid_InitParam() {
|
|
ColumnCount = GridColumnCount,
|
|
RowCount = GridRowCount,
|
|
UnitLength = UnitLength,
|
|
MarkPower = MarkPower,
|
|
MarkSpeed = MarkSpeed,
|
|
MarkLength = MarkLength,
|
|
IsModulation = IsModulation,
|
|
Frequnecy = Frequency,
|
|
PulseDulation = PulseDuration
|
|
};
|
|
|
|
IsSequenceRunning_MarkGrid = true;
|
|
_SeqMarkGrid.Start(param, OnCompleteMarkGrid);
|
|
|
|
}
|
|
|
|
private void OnCompleteMarkGrid(SequenceActionResult res)
|
|
{
|
|
if (res != null) {
|
|
if (res.Param is SeqMarkGrid_OutParam result && result.Success == true) {
|
|
IsSequenceRunning_MarkGrid = false;
|
|
MessageUtil.ShowSuccessToast(string.Format("Success SeqMarkGrid"));
|
|
return;
|
|
}
|
|
}
|
|
|
|
IsSequenceRunning_MarkGrid = false;
|
|
MessageUtil.ShowWarningToast(string.Format("Fail SeqMarkGrid"));
|
|
}
|
|
|
|
private void PerformCmdStopMarkGrid(object obj)
|
|
{
|
|
if (_SeqMarkGrid.RunState == SequenceRunState.Idle) {
|
|
return;
|
|
}
|
|
|
|
IsSequenceRunning_MarkGrid = false;
|
|
_SeqMarkGrid.Stop();
|
|
}
|
|
|
|
private void PerformCmdRunScannerCalibration(object obj)
|
|
{
|
|
if (_ScannerConfig.UseMarkingOnTheFly == true) {
|
|
MessageUtil.ShowWarningToast(string.Format("Please Check Marking on the Fly(MOTF)"));
|
|
return;
|
|
}
|
|
|
|
if (VisionCorrectionList.Count <= 0) {
|
|
MessageUtil.ShowWarningToast(string.Format("\"Please Check Data Correction apply"));
|
|
return;
|
|
}
|
|
|
|
var result = MessageUtil.ShowYesNoMessageDialog("Scanner Calibration", "Start Scanner Calibration Sequence?\nCheck Calibration Type\nTo calibrate after MarkGrid, CalType set to Laser");
|
|
if (result == false) {
|
|
return;
|
|
}
|
|
|
|
if (_SeqScannerCalibration.RunState == SequenceRunState.Running) {
|
|
MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "_SeqScannerCalibration"));
|
|
return;
|
|
}
|
|
|
|
var param = new SeqScannerCalibration_InitParam() {
|
|
FovInfo = _FovInfo,
|
|
IsVisionCalibration = IsVisionCalibration,
|
|
|
|
ColumnCount = GridColumnCount,
|
|
RowCount = GridRowCount,
|
|
UnitLength = UnitLength,
|
|
TiltingDegree = TiltingDegree,
|
|
|
|
CheckOffset = OffsetThreshold,
|
|
MasterPosOffsetX = MPosOffsetX, // ian0513, 원본에는 MPosOffsetY 로 되어 있던데... 확인 필요.
|
|
MasterPosOffsetY = MPosOffsetY,
|
|
|
|
//1step Calibration Param
|
|
Is1StepCalibration = Is1StepCalibration,
|
|
RetryNum = RetryNum,
|
|
SelectedRowIndex = SelectedRowIndex
|
|
};
|
|
|
|
IsSequenceRunning_ScannerCalibration = true;
|
|
_SeqScannerCalibration.Start(param, OnCompleteScannerCalibration);
|
|
|
|
}
|
|
|
|
private void OnCompleteScannerCalibration(SequenceActionResult res)
|
|
{
|
|
if (res != null) {
|
|
if (res.Param is SeqScannerCalibration_OutParam result && result.Success == true) {
|
|
IsSequenceRunning_ScannerCalibration = false;
|
|
MessageUtil.ShowSuccessToast(string.Format("Success SeqScannerCalibration"));
|
|
return;
|
|
}
|
|
}
|
|
|
|
IsSequenceRunning_ScannerCalibration = false;
|
|
MessageUtil.ShowWarningToast(string.Format("Fail SeqScannerCalibration"));
|
|
}
|
|
|
|
private void PerformCmdStopScannerCalibration(object obj)
|
|
{
|
|
if (_SeqScannerCalibration.RunState == SequenceRunState.Idle) {
|
|
return;
|
|
}
|
|
|
|
IsSequenceRunning_ScannerCalibration = false;
|
|
_SeqScannerCalibration.Stop();
|
|
}
|
|
public void MoveScanner()
|
|
{
|
|
double scannerPosX = VisionCorrectionList[_SelectedRowIndex].MasterX;
|
|
double scannerPosY = VisionCorrectionList[SelectedRowIndex].MasterY;
|
|
var res = MessageUtil.ShowYesNoMessageDialog("Scanner", $"Move Scanner to Postion(X : {scannerPosX}, Y: {scannerPosY}) of Selected Cell?");
|
|
if (res) {
|
|
_Scanner.JumpAbs(scannerPosX, scannerPosY, eFunctionType.COMMAND);
|
|
}
|
|
}
|
|
private void InitializeDataGridViewItem(int columnCount, int rowCount, float unitLength, float tiltingDegree)
|
|
{
|
|
try {
|
|
VisionCorrectionList.Clear();
|
|
|
|
for (int column = 0; column < columnCount; column++) {
|
|
for (int row = 0; row < rowCount; row++) {
|
|
CorrectionUnit dtItem = new CorrectionUnit();
|
|
dtItem.Column = column + 1;
|
|
dtItem.Row = row + 1;
|
|
|
|
float tempX = unitLength * ((column % columnCount) - (columnCount - 1) / 2f);
|
|
float tempY = unitLength * ((row % rowCount) - (rowCount - 1) / 2f);
|
|
float masterX = tempX * (float)Math.Cos(tiltingDegree * Math.PI / 180) - tempY * (float)Math.Sin(tiltingDegree * Math.PI / 180);
|
|
float masterY = tempX * (float)Math.Sin(tiltingDegree * Math.PI / 180) + tempY * (float)Math.Cos(tiltingDegree * Math.PI / 180);
|
|
|
|
dtItem.MasterX = masterX;
|
|
dtItem.MasterY = masterY;
|
|
|
|
dtItem.VisionX = 0;
|
|
dtItem.VisionY = 0;
|
|
VisionCorrectionList.Add(dtItem);
|
|
}
|
|
}
|
|
} catch (Exception) {
|
|
MessageUtil.CreateAndShowMessageDialog("Correction", "Init Table Fail.");
|
|
}
|
|
}
|
|
private void PerformCmdFindPattern(object obj)
|
|
{
|
|
var cameraDisplay = CameraDisplayManager.GetDisplay(_FovInfo, eDisplayType.Pattern) as CameraDisplay;
|
|
var procPatternInfo = VisionRecipeManager.GetProcPatternInfo(_FovInfo, "Align1", eProcPatternId.ProcPattern1);
|
|
var patternInfo = _PatternAgent.GetPatternInfo(_FovInfo, procPatternInfo.PatternId);
|
|
|
|
// Live GrabImage 또는 LoadImage 둘다 사용할 수 있도록 한다.
|
|
if (IsGrabLiveLimage) {
|
|
_CameraAgent.GrabSync(cameraDisplay, ref _GrabImage);
|
|
} else {
|
|
_GrabImage = cameraDisplay.GetImage();
|
|
}
|
|
if (_GrabImage != null) {
|
|
_PatternResult = _PatternAgent.Find(patternInfo, _GrabImage, cameraDisplay);
|
|
} else {
|
|
Log.W("GrabImage is Null");
|
|
}
|
|
|
|
if(_PatternResult.Status == eFoundStatus.FoundOK) {
|
|
var resultsList = _PatternResult.Results.ToList();
|
|
|
|
PatternCorrectionList.Clear();
|
|
for (int i = 0; i < resultsList.Count; i++) {
|
|
PatternCorrectionUnit patternCorrectionUnit = new PatternCorrectionUnit();
|
|
patternCorrectionUnit.Index = i;
|
|
patternCorrectionUnit.PosX = Math.Round(resultsList[i].ImagePosition.X, 3);
|
|
patternCorrectionUnit.PosY = Math.Round(resultsList[i].ImagePosition.Y, 3);
|
|
PatternCorrectionList.Add(patternCorrectionUnit);
|
|
}
|
|
|
|
_PatternAgent.Draw(patternInfo, _PatternResult, cameraDisplay);
|
|
} else {
|
|
Log.W("Pattern is not found.");
|
|
}
|
|
}
|
|
|
|
private void PerformCmdCalculateDistance(object obj)
|
|
{
|
|
try {
|
|
List<double> lsDistances = new List<double>();
|
|
foreach (var item1 in PatternCorrectionList) {
|
|
double dDistanceMin = double.MaxValue;
|
|
foreach (var item2 in PatternCorrectionList) {
|
|
if (item1 == item2) continue;
|
|
double dDistance = Math.Sqrt(Math.Pow(item2.PosX - item1.PosX, 2) + Math.Pow(item2.PosY - item1.PosY, 2));
|
|
if (dDistance > PixelDistanceMin && dDistance < PixelDistanceMax)
|
|
lsDistances.Add(dDistance);
|
|
if (dDistance < dDistanceMin) {
|
|
dDistanceMin = dDistance;
|
|
}
|
|
}
|
|
if (lsDistances.Count > 0) {
|
|
item1.Distance = lsDistances.Average();
|
|
|
|
} else {
|
|
item1.Distance = dDistanceMin;
|
|
}
|
|
}
|
|
|
|
if (PatternCorrectionList.Count > 0) {
|
|
DistanceAverage = Math.Round(PatternCorrectionList.Average(x => x.Distance), 3);
|
|
} else {
|
|
DistanceAverage = 0;
|
|
}
|
|
|
|
LensMagnification = (DistanceAverage * _SystemParameter.CameraPixelSize) / (ReferenceDistance * 1000.0);
|
|
} catch (Exception e) {
|
|
Log.W($"{e.Message}");
|
|
}
|
|
}
|
|
|
|
private void PerformCmdGetCenterCount(object obj)
|
|
{
|
|
_Scanner.GetXYPos(out double currentX, out double currentY);
|
|
|
|
// Vision Scanner Calibration인 경우
|
|
int visionBitX = (int)(currentX * _Scanner.Config.ScaleXYFactor);
|
|
int visionBitY = (int)(currentY * _Scanner.Config.ScaleXYFactor);
|
|
|
|
VisionCorrectionList[SelectedRowIndex].VisionX = visionBitX;
|
|
VisionCorrectionList[SelectedRowIndex].VisionY = visionBitY;
|
|
}
|
|
|
|
}
|
|
public class CorrectionUnit : NotifyPropertyChangedBase
|
|
{
|
|
private int _Column;
|
|
public int Column { get => _Column; set => SetProperty(ref _Column, value); }
|
|
private int _Row;
|
|
public int Row { get => _Row; set => SetProperty(ref _Row, value); }
|
|
|
|
private float _MasterX;
|
|
public float MasterX { get => _MasterX; set => SetProperty(ref _MasterX, value); }
|
|
private float _MasterY;
|
|
public float MasterY { get => _MasterY; set => SetProperty(ref _MasterY, value); }
|
|
|
|
private int _VisionX;
|
|
public int VisionX { get => _VisionX; set => SetProperty(ref _VisionX, value); }
|
|
private int _VisionY;
|
|
public int VisionY { get => _VisionY; set => SetProperty(ref _VisionY, value); }
|
|
}
|
|
public class PatternCorrectionUnit : NotifyPropertyChangedBase
|
|
{
|
|
public int Index { get; set; }
|
|
private double _PosX;
|
|
public double PosX { get => _PosX; set => SetProperty(ref _PosX, value); }
|
|
private double _PosY;
|
|
public double PosY { get => _PosY; set => SetProperty(ref _PosY, value); }
|
|
// Distance : 가장 가까운 cross line 과의 거리
|
|
private double _Distance;
|
|
public double Distance { get => _Distance; set => SetProperty(ref _Distance, value); }
|
|
}
|
|
}
|